1

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 then I 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?

U. Windl
  • 3,480
  • 26
  • 54
user840930
  • 5,214
  • 21
  • 65
  • 94

1 Answers1

2

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>
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • there are several nodes in the source xml with the tag and I need to find a particular node that has the specific text "Some text". How do I extract only this node with just this specific text "Some text" and not the other nodes? – user840930 Jan 29 '12 at 21:45
  • @user840930: Please edit the question and provide all relevant information. Next time you are asking a question be more attentive. I updated my answer to reflect your comment. – Dimitre Novatchev Jan 29 '12 at 22:04