1

我一直试图弄清楚这是我们的一段时间,但没有运气。

我有一个 for each 循环专门针对具有特定属性的节点,但不知何故 for each 条件似乎不起作用。

我有以下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>

参数 inputEnv 是“测试”,参数 $subEnvValue 是“env”。我得到的输出是

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

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

testing1:group2PropValues

4

1 回答 1

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
于 2013-05-16T02:09:50.447 回答