3

I want to remove all the nodes in XML datatype column; matching the attribute condition for all the records.For example <resource> node which has attribute "type" whose value is like '%audio%'.

Input:

<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>

Output:

<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>

Here is the query which i have tried but didn't work.

;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"]')

Thanks!

2 Answers 2

4

If you want to remove everything that has type like audio you could use 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

Output:

<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>

Alternatively in any position in XML document:

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

LiveDemo2

Sign up to request clarification or add additional context in comments.

Comments

3

Try it like this, it's a namespaces issue...

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;

1 Comment

yup - alternatively add the NS: prefix to ech node down the chain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.