XSLT - 应用模板中包含多个节点的通用规则

时间:2012-05-07 12:29:22

标签: xslt

我正在根据父亲的一个字段对Grand Parent进行排序。源文件看起来像

<Root>
    <AllData>
        <Data_not_to_be_sorted>
            <Additional_data1>
                <Some_test_data1/>
                <Some_test_data2/>
            </Additional_data1>
        </Data_not_to_be_sorted>
        <RealData>
            <Some_data1/>
            <Some_data2/>
            <GrandFather>
                <Data_required_as_it_is></Data_required_as_it_is>
                    <Father>
                        <Value>4</Value>
                        <Name>name in 4</Name>
                    </Father>
            </GrandFather>
            <GrandFather>
                <Data_required_as_it_is></Data_required_as_it_is>
                <Father>
                    <Value>3</Value>
                    <Name>name in 3</Name>
                </Father>
            </GrandFather>
        </RealData>
        <RealData>
            <Some_data1/>
            <Some_data2/>
            <GrandFather>
                <Data_required_as_it_is></Data_required_as_it_is>
                <Father>
                    <Value>2</Value>
                    <Name>name in 2</Name>
                </Father>
            </GrandFather>
            <GrandFather>
                <Data_required_as_it_is></Data_required_as_it_is>
                <Father>
                    <Value>1</Value>
                    <Name>name in 1</Name>
                </Father>
            </GrandFather>
        </RealData>
    </AllData>
</Root>

我使用的XSLT代码如下:

<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="RealData">
<xsl:copy>
<xsl:apply-templates select="Data_required_as_it_is"></xsl:apply-templates>
<xsl:apply-templates select="GrandFather">
<xsl:sort select="Father/Value" data-type="number"/>
</xsl:apply-templates>

</xsl:copy>

</xsl:template>

</xsl:stylesheet>

代码运行良好......我的查询是 - 我可以为

编写通用行吗?

Data_required_as_it_is。想象一下,我为“Data_required_as_it_is”提供了20个不同的xml标签,所以我需要手动编写所有这些标签,或者只是以通用方式编写它们......

代码的输出如下:

<Root>
    <AllData>
        <Data_not_to_be_sorted>
            <Additional_data1>
                <Some_test_data1/>
                <Some_test_data2/>
            </Additional_data1>
        </Data_not_to_be_sorted>
        <RealData>
            <Some_data1/>
            <Some_data2/>
            <GrandFather>
                <Data_required_as_it_is></Data_required_as_it_is>
                    <Father>
                        <Value>3</Value>
                        <Name>name in 3</Name>
                    </Father>
            </GrandFather>
            <GrandFather>
                <Data_required_as_it_is></Data_required_as_it_is>
                <Father>
                    <Value>4</Value>
                    <Name>name in 4</Name>
                </Father>
            </GrandFather>
        </RealData>
        <RealData>
            <Some_data1/>
            <Some_data2/>
            <GrandFather>
                <Data_required_as_it_is></Data_required_as_it_is>
                <Father>
                    <Value>1</Value>
                    <Name>name in 1</Name>
                </Father>
            </GrandFather>
            <GrandFather>
                <Data_required_as_it_is></Data_required_as_it_is>
                <Father>
                    <Value>2</Value>
                    <Name>name in 2</Name>
                </Father>
            </GrandFather>
        </RealData>
    </AllData>
</Root>

2 个答案:

答案 0 :(得分:1)

如果您想要匹配此时不是 GrandFather 元素的任何内容,您应该可以执行以下操作:

<xsl:apply-templates select="*[not(self::GrandFather)]"></xsl:apply-templates> 

请注意,如果在任何现有的 GrandFather 元素之后有元素,则在这种情况下,它们将被移动到输出中排序的 GrandFather 元素之前。

答案 1 :(得分:1)

<xsl:template match="RealData">
      <xsl:copy>
          <xsl:apply-templates select="Data_required_as_it_is"></xsl:apply-templates>
          <xsl:apply-templates select="GrandFather">
              <xsl:sort select="Father/Value" data-type="number"/>
          </xsl:apply-templates>
      </xsl:copy>
  </xsl:template>

可以使用更通用的代码

<xsl:template match="RealData">
    <xsl:copy>
        <xsl:apply-templates>
            <xsl:sort select="self::GrandFather/Father/Value" data-type="number"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

注意:这将在任何GrandFather节点之前对任何非GrandFather节点进行排序,并按GrandFather元素对Father/Value元素进行指定排序1}}元素。

如果希望非GrandFather元素仍然散布在GrandFather元素中,这也可以实现 - 如果感兴趣,可以提出另一个问题。