使用XSLT 1.0浏览不同级别的节点

时间:2017-09-25 13:17:12

标签: xml xslt xpath xslt-1.0

我正处理一个开始变得非常无聊的问题。实际上,这是我阻止的情况: 这是我的XML示例:

<Classification>
    <data>
        <value>String1</value>
        <value>String2</value>
        <value>content1</value>
    </data>
    <data>
        <value></value>
        <value></value>
        <value>
            <part>content3</part>
            <part>content2</part>
            <part>content1</part>
        </value>
    </data>
    <data>
        <value></value>
        <value></value>
        <value>content1</value>
    </data>
    <data>
        <value></value>
        <value></value>
        <value>
            <part>content2</part>
            <part>content4</part>
        </value>
    </data>
</Classification>

以下是我想要的结果:

<Classification>
    <data>
        <value>content1</value>
    </data>
    <data>
        <value>content2</value>
    </data>
    <data>
        <value>content3</value>
    </data>
    <data>
        <value>content4</value>
    </data>
    <data>
        <value>String1</value>
    </data>
    <data>
        <value>String2</value>
    </data>
</Classification>

我想爆炸我的xml只输出唯一值。但是,我无法解决可能不同的价值问题[3]。

我已经使用了前一个兄弟和递归。这是我使用的xsl:

<xsl:template name="clearClassificationWithPart">
    <xsl:param name="recursion"/>
    <xsl:choose>
        <xsl:when test="$recursion > 0">
            <xsl:for-each select="data[
                not(./value[$recursion] = preceding-sibling::data/value[$recursion])
                and not(./value[$recursion]/part = preceding-sibling::data/value[$recursion])
                and not(./value[$recursion] = preceding-sibling::data/value[$recursion]/part)
                and not(./value[$recursion]/part = preceding-sibling::data/value[$recursion]/part)]">
                <xsl:choose>
                    <xsl:when test="./value[$recursion]/part">
                        <xsl:for-each select="./value[$recursion]/part">
                            <data>
                                <value><xsl:value-of select="." /></value>
                            </data>
                        </xsl:for-each>
                    </xsl:when>
                    <xsl:otherwise>
                        <data>
                            <value><xsl:value-of select="./value[$recursion]" /></value>
                        </data>
                    </xsl:otherwise>
                </xsl:choose>      
            </xsl:for-each>

            <xsl:call-template name="clearClassificationWithPart">
                <xsl:with-param name="recursion" select="$recursion - 1"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise/>
    </xsl:choose>
</xsl:template>

我使用的是XSLT 1.0。

有人有想法吗? 谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

使用支持EXSLT set:distinct()扩展功能的处理器,您可以执行以下操作:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:set="http://exslt.org/sets"
extension-element-prefixes="set">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/Classification">
    <xsl:copy>
        <xsl:for-each select="set:distinct(data/value/text() | data/value/part/text())">
           <data>
                <value>
                    <xsl:value-of select="."/>
                </value>
            </data>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

产生以下结果:

<?xml version="1.0" encoding="utf-8"?>
<Classification>
  <data>
    <value>String1</value>
  </data>
  <data>
    <value>String2</value>
  </data>
  <data>
    <value>content1</value>
  </data>
  <data>
    <value>content3</value>
  </data>
  <data>
    <value>content2</value>
  </data>
  <data>
    <value>content4</value>
  </data>
</Classification>