Xml – XSLT or XPath: how to find a node with a specific tag and text then extract it into a new xml file

extractinodexmlxslt

I need to find a particular node in an xml file, <example>Some text</example>

Then I want to extract this node and it's subelements from the xml file and write it into a new xml file and I then need to extract the other remaining xml nodes in the original xml file minus the extracted node into the new xml file following the extracted node.

How can I do this with xslt or xpath?

Best Answer

Here is how to output all nodes minus the specific node and its subtree:

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>

     <xsl:template match="example[. = 'Some text']"/>
</xsl:stylesheet>

when this transformation is applied on the following XML document (none was provided!):

<a>
            <example>Some different text</example>
    <b>
        <c>
            <example>Some text</example>
        </c>
            <example>Some other text</example>
    </b>
</a>

the wanted, correct result is produced:

<a>
    <b>
        <c></c>
    </b>
</a>

Here is how to extract only the wanted node and its subtree:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="example[. = 'Some text']">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

when applied on the same XML document (above), the result now is:

<example>Some text</example>

Two different result documents cannot be produced in a single XSLT 1.0 transformation.

Here is an XSLT 2.0 transformation that outputs the first result and writes to a file the second result:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vResult2">
  <xsl:apply-templates mode="result2"/>
 </xsl:variable>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="example[. = 'Some text']"/>

 <xsl:template match="/">
  <xsl:apply-templates/>

  <xsl:result-document href="file:///c:/temp/delete/result2.xml">
   <xsl:sequence select="$vResult2"/>
  </xsl:result-document>
 </xsl:template>

 <xsl:template mode="result2" match="example[. = 'Some text']">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template mode="result2" match="text()"/>
</xsl:stylesheet>
Related Topic