how to select specific node sets in xslt

xslt-1.0

Solution

This short and simple transformation:

<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=
  "node()[not(self::root or ancestor-or-self::config or ancestor-or-self::row)]">
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<root>
    <postdate>2011-03-30</postdate>
    <location>84</location>
    <meal>07:36</meal>
    <config>
        <postdate>2011-03-30</postdate>
        <location>84</location>
        <meal>07:36</meal>
        <checknumber>91339082011-03-30T07:36:12</checknumber>
    </config>
    <items>
        <row>
            <descriptor>7297364</descriptor>
            <qty>1</qty>
            <price>33</price>
            <value>33</value>
            <recordtype>1</recordtype>
            <postdate>2011-03-30</postdate>
            <location>84</location>
        </row>
        <row>
            <descriptor>7794473</descriptor>
            <qty>1</qty>
            <price>60</price>
            <value>60</value>
            <recordtype>1</recordtype>
            <postdate>2011-03-30</postdate>
            <location>84</location>
        </row>
    </items>
    <tenders>
        <row>
            <id>13</id>
            <value>117.99</value>
            <recordtype>2</recordtype>
            <postdate>2011-03-30</postdate>
            <location>84</location>
        </row>
    </tenders>
    <taxes>
        <row>
            <id>2</id>
            <value>8.25</value>
            <recordtype>3</recordtype>
            <postdate>2011-03-30</postdate>
            <location>84</location>
        </row>
    </taxes>
</root>

produces the wanted, correct result:

<root>
   <config>
      <postdate>2011-03-30</postdate>
      <location>84</location>
      <meal>07:36</meal>
      <checknumber>91339082011-03-30T07:36:12</checknumber>
   </config>
   <row>
      <descriptor>7297364</descriptor>
      <qty>1</qty>
      <price>33</price>
      <value>33</value>
      <recordtype>1</recordtype>
      <postdate>2011-03-30</postdate>
      <location>84</location>
   </row>
   <row>
      <descriptor>7794473</descriptor>
      <qty>1</qty>
      <price>60</price>
      <value>60</value>
      <recordtype>1</recordtype>
      <postdate>2011-03-30</postdate>
      <location>84</location>
   </row>
   <row>
      <id>13</id>
      <value>117.99</value>
      <recordtype>2</recordtype>
      <postdate>2011-03-30</postdate>
      <location>84</location>
   </row>
   <row>
      <id>2</id>
      <value>8.25</value>
      <recordtype>3</recordtype>
      <postdate>2011-03-30</postdate>
      <location>84</location>
   </row>
</root>

Explanation:

Using and overriding the identity rule.

Proper use of the `ancestor-or-self::` axis.

Problem

The xslt I'm currently using generates all the tags on the root. I need to get the `<row>` sets and `<config>` set. Source Xml: ``` <root> <postdate>2011-03-30</postdate> <location>84</location> <meal>07:36</meal> <config> <postdate>2011-03-30</postdate> <location>84</location> <meal>07:36</meal> <checknumber>91339082011-03-30T07:36:12</checknumber> </config> <items> <row> <descriptor>7297364</descriptor> <qty>1</qty> <price>33</price> <value>33</value> <recordtype>1</recordtype> <postdate>2011-03-30</postdate> <location>84</location> </row> <row> <descriptor>7794473</descriptor> <qty>1</qty> <price>60</price> <value>60</value> <recordtype>1</recordtype> <postdate>2011-03-30</postdate> <location>84</location> </row> </items> <tenders> <row> <id>13</id> <value>117.99</value> <recordtype>2</recordtype> <postdate>2011-03-30</postdate> <location>84</location> </row> </tenders> <taxes> <row> <id>2</id> <value>8.25</value> <recordtype>3</recordtype> <postdate>2011-03-30</postdate> <location>84</location> </row> </taxes> </root> ``` Attempted Xslt: ``` <xsl:stylesheet version="1.0" exclude-result-prefixes="msxsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <xsl:template match="row/*"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> ``` Desired Output: ``` <root> <config> <postdate>2011-03-30</postdate> <location>84</location> <meal>07:36</meal> <checknumber>91339082011-03-30T07:36:12</checknumber> </config> <row> <descriptor>7297364</descriptor> <qty>1</qty> <price>33</price> <value>33</value> <recordtype>1</recordtype> <postdate>2011-03-30</postdate> <location>84</location> </row> <row> <descriptor>7794473</descriptor> <qty>1</qty> <price>60</price> <value>60</value> <recordtype>1</recordtype> <postdate>2011-03-30</postdate> <location>84</location> </row> <row> <id>13</id> <value>117.99</value> <recordtype>2</recordtype> <postdate>2011-03-30</postdate> <location>84</location> </row> <row> <id>2</id> <value>8.25</value> <recordtype>3</recordtype> <postdate>2011-03-30</postdate> <location>84</location> </row> </root> ```

Original source