如何在xslt中选择特定的节点集

时间:2012-11-27 21:01:50

标签: xslt-1.0

我正在使用的xslt生成根目录上的所有标记。 我需要设置<row>集和<config>

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

尝试过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>

期望的输出:

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

2 个答案:

答案 0 :(得分:7)

这个简短而简单的转型

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

应用于提供的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>

会产生想要的正确结果:

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

<强>解释

  1. 使用并覆盖 identity rule

  2. 正确使用ancestor-or-self::轴。

答案 1 :(得分:0)

我知道了。这个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="/">
        <root>
            <xsl:for-each select="//row">
                <row>
                    <xsl:apply-templates/>
                </row>
            </xsl:for-each>
            <xsl:for-each select="//config">
                <config>
                    <xsl:apply-templates/>
                </config>
            </xsl:for-each>
        </root>
    </xsl:template>
    <xsl:template match="*">
        <xsl:element name="{name()}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>