xsl:for-each循环,其属性与参数匹配

时间:2013-05-16 01:52:41

标签: xslt foreach

我一直在试图解决这个问题,但没有运气。

我为每个循环专门定位到具有特定属性的节点,但不知何故,每个条件似乎都不起作用。

我有以下xml

   <?xml version="1.0" encoding="UTF-8"?>
<application-template xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <config>
        <env value="testing">
            <subEnv value="env">
                <group value="group2s">
                    <group value="group2as">
                        <prop value="group2Props">group2PropValues</prop>
                    </group>
                </group>
            </subEnv>
            <subEnv value="misc1">
                <group value="group2s">
                    <group value="group2as">
                        <prop value="group2Props">group2sPropValues</prop>
                    </group>
                </group>
                <group value="group2s1">
                    <group value="group2as1">
                        <prop value="group2Props">group2s1PropValues</prop>
                    </group>
                </group>
            </subEnv>
        </env>
        <env value="testingA">
            <subEnv value="env">
                <group value="test2">
                    <group value="test2a">
                        <group value="test2ab">
                            <prop value="group2Props">testingAGroup2PropValues</prop>
                        </group>
                    </group>
                </group>
            </subEnv>
        </env>
    </config>
</application-template>

使用以下xsl

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:param name="inputEnv"/>
    <xsl:variable name="env" select="/application-template/config/env[@value=$inputEnv]"/>

    <xsl:strip-space elements="*"/>
    <xsl:output method="text" indent="no"/>

    <xsl:template match="/">
        <xsl:call-template name="ou">
            <xsl:with-param name="subEnvPos" select="$env/subEnv"/>
            <xsl:with-param name="subEnvValue" select="$env/subEnv/@value"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="ou">
        <xsl:param name="subEnvPos"/>
        <xsl:param name="subEnvValue"/>

        <xsl:variable name="test" select="/application-template/config/env[@value=$inputEnv]/subEnv[@value=$subEnvValue]"/>

        <xsl:for-each select="$test/group">
            testing1:
            <xsl:value-of select="$test"/>
        </xsl:for-each>

    </xsl:template>
</xsl:stylesheet>

param inputEnv为“testing”,param $ subEnvValue为“env”。我得到的输出是

testing1:group2PropValues testing1:group2PropValues testing1:group2PropValues testing1:group2PropValues

但我想循环一次,因为条件是匹配subenv node = $ subEnvValue(这是“env”)。我希望的输出是

testing1:group2PropValues

1 个答案:

答案 0 :(得分:1)

我认为不是您当前的代码

<xsl:template match="/">
    <xsl:call-template name="ou">
        <xsl:with-param name="subEnvPos"
           select="$env/subEnv"/>
        <xsl:with-param name="subEnvValue"
           select="$env/subEnv/@value"/>
    </xsl:call-template>
</xsl:template>

你想要这样的东西

<xsl:template match="/">
    <xsl:call-template name="ou">
        <xsl:with-param name="subEnvPos"
           select="$env/subEnv[1]"/>
        <xsl:with-param name="subEnvValue"
           select="$env/subEnv[1]/@value"/>
    </xsl:call-template>
</xsl:template>

通过此修改,现在完整的XSLT代码为:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:param name="inputEnv" select="'testing'"/>

    <xsl:variable name="env" select=
    "/application-template/config/env[@value=$inputEnv]"/>

    <xsl:strip-space elements="*"/>
    <xsl:output method="text" indent="no"/>

    <xsl:template match="/">
        <xsl:call-template name="ou">
            <xsl:with-param name="subEnvPos"
               select="$env/subEnv[1]"/>
            <xsl:with-param name="subEnvValue"
               select="$env/subEnv[1]/@value"/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template name="ou">
        <xsl:param name="subEnvPos"/>
        <xsl:param name="subEnvValue"/>
        <xsl:variable name="test" select=
        "/application-template/config/env
                 [@value=$inputEnv]/subEnv[@value=$subEnvValue]"/>
        <xsl:for-each select="$test/group">
testing1:
            <xsl:value-of select="$test"/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

,当应用于提供的XML文档时:

<application-template xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <config>
        <env value="testing">
            <subEnv value="env">
                <group value="group2s">
                    <group value="group2as">
                        <group value="group2bs">
                            <prop value="group2Props">group2PropValues</prop>
                        </group>
                    </group>
                </group>
            </subEnv>
            <subEnv value="misc1">
                <group value="group2s">
                    <group value="group2as">
                        <group value="group2bs">
                            <prop value="group2Props">group2sPropValues</prop>
                        </group>
                    </group>
                </group>
                <group value="group2s1">
                    <group value="group2as1">
                        <group value="group2bs1">
                            <prop value="group2Props">group2s1PropValues</prop>
                        </group>
                    </group>
                </group>
            </subEnv>
            <subEnv value="misc2">
                <group value="group2sMisc2">
                    <group value="group2asMisc2">
                        <group value="group2bsMisc2">
                            <prop value="group2Props">group2PropValuesMisc2</prop>
                        </group>
                    </group>
                </group>
            </subEnv>
        </env>
    </config>
</application-template>

生成了想要的结果

testing1:
            group2PropValues

<强>更新

在OP在评论中解释他想要什么之后,这是一个简短的解决新问题的方法:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>
 <xsl:param name="vinputEnv" select="'testing'"/>

 <xsl:template match="/*/*/env">
  <xsl:if test="@value = $vinputEnv">
    <xsl:for-each select="descendant::*[not(*)]">
      <xsl:value-of select="concat('testing1: ', ., '&#xA;')"/>
    </xsl:for-each>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档(上图)时,会生成所需的正确结果

testing1: group2PropValues
testing1: group2sPropValues
testing1: group2s1PropValues
testing1: group2PropValuesMisc2