【问题标题】:xsl:for-each loop with attribute matching with parameterxsl:for-each 循环,属性与参数匹配
【发布时间】:2013-05-16 01:52:40
【问题描述】:

我已经尝试了一段时间,但没有成功。

我有一个 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 是“testing”,参数 $subEnvValue 是“env”。我得到的输出是

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

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

testing1:group2PropValues

【问题讨论】:

    标签: xslt foreach


    【解决方案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
    

    【讨论】:

    • @user2387761,请更新这个问题——理解这条评论很有挑战性。
    • 对不起...我是这里的新手,我正在尝试向 cmets 添加更多代码,但我似乎无法正确格式化新代码。因此,我更新了原始 XML。我正在考虑更进一步……就是在之后,我喜欢回到ou模板来处理下一个。另外,我喜欢做的另一件事是给定“inputEnv”,它将处理 $inputEnv 指定的 节点(外部提供)
    • @user2387761,如果您能很好地解释(在问题中)您想从给定的 XML 文档中生成什么以及转换应该实现的规则/约束是什么,那将是最好的。我有 99% 的把握,一旦我们知道您想要实现什么,就会找到更短、更简单、更优雅的解决方案。
    • 谢谢...如果 inputEnv 是“正在测试” testing1:group2PropValues testing1:group2sPropValues testing1:group2s1PropValues testing1:group2PropValuesMisc2,我正在寻找输出。如果 inputEnv 为“testingA”,则输出将为 testing1:testingAGroup2PropValues testing1:testingAGroup3PropValues。 inputEnv 是在不同时间由外部提供的,因此基于 inputEnv 可能会有不同的输出
    • @user2387761,不,你需要从节点、元素、结构的角度来说话——比如:“我需要输出每个名为 XYZ 的元素的字符串值”。此外,最好提供一个更简单、更小的示例,它仍然可以说明问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    相关资源
    最近更新 更多