0

我将 xml 文件存储在 SQL Server 表中的 xml 数据类型中。现在我想获取一些片段(使用 xquery),然后用修改后的片段更新片段(使用 xquery)。我需要一些建议。

我有删除节点的代码,如下所示,但在删除时我需要在同一个地方插入修改后的节点。如何才能做到这一点?

--SET @doc.modify('delete (/DATA/SDACTS)')

如果我想删除一个节点,但是在同一位置插入修改后的节点怎么办?

接下来我想删除其值将作为查询字符串传递的节点,所以我必须建立字符串

像下面

DECLARE @x XML 

SET @x = '
<DATA>
  <SDACTS>
    <SDACT TYPE="Economy" COLOUR="0xff0000" />
    <SDACT TYPE="Environment" COLOUR="0x00ff00" />
    <SDACT TYPE="People" COLOUR="0x0000ff" />
    <SDACT TYPE="Society" COLOUR="0xff00ff" />
  </SDACTS>
<LOCATIONS>
    <CONTINENT TITLE="South America">
      <COUNTRY TITLE="Chile">
        <HEADOFFICE>Santiago</HEADOFFICE>
        <ADDRESS>
          &lt;p&gt;Pedro de Valdivia 291&lt;/p&gt;&lt;p&gt;Providencia&lt;/p&gt;&lt;p&gt;Santiago&lt;/p&gt;
        </ADDRESS>
        <LATITUDE>-33.426127</LATITUDE>
        <LONGITUDE>-70.611469</LONGITUDE>
        <BUSINESSUNITS>Copper</BUSINESSUNITS>        
        <EMPLOYEES />
        <NUMBEROFBUSINESS>1</NUMBEROFBUSINESS>
      </COUNTRY>
      <COUNTRY TITLE="Brazil">
        <HEADOFFICE>Brazil</HEADOFFICE>
        <ADDRESS>
          &lt;p&gt;Pedro de Valdivia 291&lt;/p&gt;&lt;p&gt;Providencia&lt;/p&gt;&lt;p&gt;Santiago&lt;/p&gt;
        </ADDRESS>
        <LATITUDE>-38.426127</LATITUDE>
        <LONGITUDE>-60.611469</LONGITUDE>
        <BUSINESSUNITS>Zinc</BUSINESSUNITS>        
        <EMPLOYEES />
        <NUMBEROFBUSINESS>2</NUMBEROFBUSINESS>
      </COUNTRY>
    </CONTINENT>
</LOCATIONS>
</DATA>

我必须删除位于南美洲大陆的巴西国家,所以我必须保留这些作为参数,这些参数必须是动态的,因为其他国家和大陆可以来。

declare @country varchar(50)
declare @continent  varchar(50)
set @country = 'Brazil'
set @continent = 'South America'

declare @final varchar(100)
set @final = '//CONTINENT[@TITLE="' + @continent + '"]/COUNTRY[@TITLE="' + @country + '"]'
select @final
--SELECT @doc.query('sql:variable("@final")') 'XmlDesc'  This works for select statement but not for delete
SET @doc.modify('delete (sql:variable("@final"))')   This does not work and gives error.
 SELECT @doc

我的要求:

基本上我在.NET中制作了一个xml编辑工具,并且在加载巨大的xml文件时jQuery树挂起,所以我将巨大的xml文件存储在表中并调用段(子节点),然后将这些段加载到jquery树中并用户修改这些节点。我将修改后的段带到数据库中,然后想用修改后的段进行更新。

4

1 回答 1

1

编辑 2:看起来 SLQ-Server不是一个完全抱怨的 XQuery 处理器......

所以,一个更“静态”的 XQuery(很好的是模式是众所周知的):

declare variable $continent external;
declare variable $country external;
declare variable $xml as item() external;
element DATA {
   /DATA/@*,
   /DATA/*[not(self::LOCATIONS)],
   element LOCATIONS {
      /DATA/LOCATIONS/@*,
      for $cont in /DATA/LOCATIONS/CONTINENT
      return element CONTINENT {
                $cont/@*,
                for $count in $cont/COUNTRY
                return if ($cont/@TITLE=$continent and
                           $count/@TITLE=$country)
                       then $xml
                       else $count
             }
   }
}

使用此参数(使用 SQL-Server,您还可以使用sql:variable()扩展功能):

continent="'South America'"
country="'Brazil'"
xml="<COUNTRY TITLE='Brazil'><UPDATE/></COUNTRY>"

输出:

<DATA>
    <SDACTS>
        <SDACT TYPE="Economy" COLOUR="0xff0000"/>
        <SDACT TYPE="Environment" COLOUR="0x00ff00"/>
        <SDACT TYPE="People" COLOUR="0x0000ff"/>
        <SDACT TYPE="Society" COLOUR="0xff00ff"/>
    </SDACTS>
    <LOCATIONS>
        <CONTINENT TITLE="South America">
            <COUNTRY TITLE="Chile">
                <HEADOFFICE>Santiago</HEADOFFICE>
                <ADDRESS>
          &lt;p&gt;Pedro de Valdivia 291&lt;/p&gt;&lt;p&gt;Providencia&lt;/p&gt;&lt;p&gt;Santiago&lt;/p&gt;
                </ADDRESS>
                <LATITUDE>-33.426127</LATITUDE>
                <LONGITUDE>-70.611469</LONGITUDE>
                <BUSINESSUNITS>Copper</BUSINESSUNITS>
                <EMPLOYEES/>
                <NUMBEROFBUSINESS>1</NUMBEROFBUSINESS>
            </COUNTRY>
            <COUNTRY TITLE="Brazil">
                <UPDATE/>
            </COUNTRY>
        </CONTINENT>
    </LOCATIONS>
</DATA>

编辑 3:我认为您在评论中查询的正确语法是:

declare @continent varchar(100) 
declare @country varchar(100) 
declare @xml xml 
declare @count int 
declare @doc xml 
set @continent='South America' 
set @country='Brazil' 
set @xml='<COUNTRY TITLE="Brazil"><UPDATE/></COUNTRY>' 
set @count = 1 
select @doc = xmldesc from varunxmlanglo where idlanguage =1 and xmltype ='D' 
select @doc.query('
element DATA {
   /DATA/@*,
   /DATA/*[not(self::LOCATIONS)],
   element LOCATIONS {
      /DATA/LOCATIONS/@*,
      for $continent in /DATA/LOCATIONS/CONTINENT
      return element CONTINENT {
                $continent/@*,
                for $country in $continent/COUNTRY
                return if ($continent/@TITLE=sql:variable("@continent") and                                                       $country/@TITLE=sql:variable("@country"))
                       then sql:variable("@xml")
                       else $country
             }
   }
}
')

注意:在 XQuery 变量引用中有$前缀。

于 2010-10-15T13:39:50.000 回答