XSLT for-each循环迭代名称相同但属性不同的2个元素

时间:2018-07-04 07:18:42

标签: xml xslt xslt-1.0 transformation

注意:解决方案应该在XSLt 1.0中

我是XSLT的一名新手,如果对与循环有关的其他问题的解决方案可以解决我的问题,我深表歉意,但到目前为止我还没有运气。

我有一个带有多个节点的XML文件,如下所示:

<Roles>
  <field name="linecode" instance="1" value="EY"/>
  <field name="number" instance="1" value="265"/>
  <field name="linecode" instance="2" value="PK"/>
  <field name="number" instance="2" value="123"/>
  <field name="abc" instance="1" value="123"/>
  <field name="xyz" instance="1" value="123"/>
</Role>

我需要遍历这些节点并打印<field name="linecode">及其匹配实例编号<field name="number">。但是,如果我使用一个for-each循环,它将迭代<field name="linecode">s,但是打印相同的<field name="number">无效。

有什么办法可以使它们同步,例如,输出将是

EY - 265
PK - 123

我也曾尝试使用following-sibling,但是它对我不起作用。.非常感谢您的帮助。

这是我的样本xslt。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="Roles">
    <xsl:for-each select="field[@name='linecode']">
        <xsl:value-of select="@value"/>
        <xsl:text> - </xsl:text>
        <xsl:value-of select="field[@name='number' and instance='@instance']"/>
        <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
</xsl:template>

如果有人能想到一种可行的循环替代方案,我将不胜感激。

3 个答案:

答案 0 :(得分:1)

如果“匹配实例”是指紧随其后的字段元素,则可以使用

$("#id_colours_on_deck").find("div[id^=id_colours_on_deck]").each(function() {
    var value = $(this).text();
});

但是,如果“匹配实例”表示具有相同ID的数字字段,则使用

<xsl:value-of select="following-sibling::field[1]/@value"/>

答案 1 :(得分:0)

您想要的表达式是这个。

<xsl:value-of select="../field[@name='number' and @instance=current()/@instance]/@value"/>

请注意一开始使用../。如果您只是<xsl:value-of select="field.." />,那么当您已经定位在field元素上时,您将尝试选择一个名为field的子元素。 ..首先选择父节点,从而允许您选择同级元素。

还请注意,使用current()指的是当前位于的节点(使用xsl:for-each选择的节点)。在此处阅读“当前节点与上下文节点”:Current node vs. Context node in XSLT/XPath?

或者,您可以在此处了解有关使用键的信息。您可以通过其field属性定义一个键来查找instance元素

<xsl:key name="fields" match="field" use="@instance" />

因此,要查找元素,您可以执行此操作。

<xsl:value-of select="key('fields', @instance)[@name = 'number']/@value"/>

也尝试使用此XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="fields" match="field" use="@instance" />

<xsl:template match="Roles">
    <xsl:for-each select="field[@name='linecode']">
        <xsl:value-of select="@value"/>
        <xsl:text> - </xsl:text>
        <xsl:value-of select="key('fields', @instance)[@name = 'number']/@value"/>
        <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

答案 2 :(得分:0)

<xsl:template match="Roles">
        <xsl:for-each select="field">
            <xsl:if test="@name='linecode'">
            <xsl:value-of select="@value"/>
                <xsl:text> - </xsl:text>
            </xsl:if>

            <xsl:if test="@name='number'">
                <xsl:value-of select="@value"/>
                <xsl:text>&#xa;</xsl:text>
            </xsl:if>

        </xsl:for-each>
Also try it