删除XML节点以匹配SQLServer中的属性条件

时间:2016-03-09 16:23:08

标签: sql-server xml tsql xquery-sql

我想删除XML数据类型列中的所有节点;匹配所有记录的属性条件。例如<resource>节点,其属性为“type”,其值类似于'%audio%'。

输入:

<metadata Item="1234" version="5" packageVersion="5" xmlns="http://www.imsglobal.org/xsd/imsqti_v2p2">
  <contents>
    <content version="0" href="content_es-mx_en-us.xml" lang="es-mx" altlang="en-us">
      <resources />
    </content>
    <content version="3" href="content_en-us.xml" lang="en-us">
      <resources>
        <resource type="image/svg" href="girlwateringtomatoes2.svg" />
        <resource type="audio/ogg" href="Audio/115988A_Sound1.ogg" />
        <resource type="audio/mp4" href="Audio/115988A_Sound1.m4a" />  
      </resources>
    </content>
  </contents>
  <references />
  <brailleEncodings />
</metadata>

输出:

<metadata Item="1234" version="5" packageVersion="5" xmlns="http://www.imsglobal.org/xsd/imsqti_v2p2">
  <contents>
    <content version="0" href="content_es-mx_en-us.xml" lang="es-mx" altlang="en-us">
      <resources />
    </content>
    <content version="3" href="content_en-us.xml" lang="en-us">
      <resources>
        <resource type="image/svg" href="girlwateringtomatoes2.svg" /> 
      </resources>
    </content>
  </contents>
  <references />
  <brailleEncodings />
</metadata>

以下是我尝试过但无效的查询。

;WITH XMLNAMESPACES ('http://www.imsglobal.org/xsd/imsqti_v2p2' AS NS)
Update dbo.TableX 
SET [XML].modify('delete /NS:metadata/NS:contents/NS:content[2]/resources/resource[@type != "image/svg"]')

谢谢!

2 个答案:

答案 0 :(得分:4)

如果您要移除type audio之类的所有内容,您可以使用contains

;WITH XMLNAMESPACES ('http://www.imsglobal.org/xsd/imsqti_v2p2' AS NS)
Update TableX 
SET [XML].modify('delete /NS:metadata/NS:contents/NS:content[2]/NS:resources/NS:resource[contains(@type, "audio")]'); 

LiveDemo

输出:

<metadata xmlns="http://www.imsglobal.org/xsd/imsqti_v2p2" Item="1234" version="5" packageVersion="5">
   <contents>
      <content version="0" href="content_es-mx_en-us.xml" lang="es-mx" altlang="en-us">
         <resources />
      </content>
      <content version="3" href="content_en-us.xml" lang="en-us">
         <resources>
            <resource type="image/svg" href="girlwateringtomatoes2.svg" />
         </resources>
      </content>
   </contents>
   <references />
   <brailleEncodings />
</metadata>

或者在XML文档中的任何位置:

;WITH XMLNAMESPACES (DEFAULT 'http://www.imsglobal.org/xsd/imsqti_v2p2' )
Update TableX 
SET [XML].modify('delete //resources/resource[contains(@type, "audio")]');  

LiveDemo2

答案 1 :(得分:3)

尝试这样,这是名称空间问题......

declare @x table(myXML xml);
insert into @x values(
'<metadata Item="1234" version="5" packageVersion="5" xmlns="http://www.imsglobal.org/xsd/imsqti_v2p2">
  <contents>
    <content version="0" href="content_es-mx_en-us.xml" lang="es-mx" altlang="en-us">
      <resources />
    </content>
    <content version="3" href="content_en-us.xml" lang="en-us">
      <resources>
        <resource type="image/svg" href="girlwateringtomatoes2.svg" />
        <resource type="audio/ogg" href="Audio/115988A_Sound1.ogg" />
        <resource type="audio/mp4" href="Audio/115988A_Sound1.m4a" />  
      </resources>
    </content>
  </contents>
  <references />
  <brailleEncodings />
</metadata>');

;WITH XMLNAMESPACES (DEFAULT 'http://www.imsglobal.org/xsd/imsqti_v2p2')
Update @x 
SET [myXML].modify('delete /metadata/contents/content[2]/resources/resource[@type != "image/svg"]')

SELECT * FROM @x;