XSL:确定跨祖先的序列

  • 本文关键字:祖先 XSL xml xslt xslt-1.0
  • 更新时间 :
  • 英文 :


我有一个XML示例,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <location id="1">
        <address>1600 Pennsylvania Avenue</address>
        <address>211B Baker Street</address>
    </location>
    <location id="1">
        <address>17 Cherry Tree Lane</address>
    </location>
    <location id="2">
        <address>350 5th Avenue</address>
    </location>
</root>

我想生成如下所示的输出:

<?xml version="1.0" encoding="utf-8"?>
<result>
    <location id="1">
        <address addressId="1">1600 Pennsylvania Avenue</address>
        <address addressId="2">211B Baker Street</address>
    </location>
    <location id="1">
        <address addressId="3">17 Cherry Tree Lane</address>
    </location>
    <location id="2">
        <address addressId="1">350 5th Avenue</address>
    </location>
</result>

这样,addressId反映具有相同id属性的所有location实例的address序列。

我以为<xsl:number>会是我的答案,但我的尝试失败了:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
    <xsl:template match="/root">
        <result>
            <xsl:for-each select="location">
                <location>
                    <xsl:attribute name="id">
                        <xsl:value-of select="@id" />
                    </xsl:attribute>
                    <xsl:for-each select="address">
                        <address>
                            <xsl:attribute name="addressId">
                                <xsl:number count="//location[@id = ../@id]/address" level="any" />
                            </xsl:attribute>
                            <!--                            
                              The rest are just my debugging attempts; 
                                curiously addressId3 and addressId4 return
                                different values?
                              -->
                            <!--
                            <xsl:attribute name="addressId2">
                                <xsl:number count="//location[@id = parent::location/@id]/address" level="any" />
                            </xsl:attribute>
                            <xsl:attribute name="addressId3">
                                <xsl:value-of select="count(//location[@id=../@id]/address)" />
                            </xsl:attribute>
                            <xsl:variable name="locId">
                                <xsl:value-of select="../@id" />
                            </xsl:variable>
                            <xsl:attribute name="addressId4">
                                <xsl:value-of select="count(//location[@id=$locId]/address)" />
                            </xsl:attribute>
                            <xsl:attribute name="addressId5">
                                <xsl:number count="//location[@id = '1']/address" level="any" />
                            </xsl:attribute>
                              -->
                            <xsl:value-of select="." />
                        </address>
                    </xsl:for-each>
                </location>
            </xsl:for-each>
        </result>
    </xsl:template>
</xsl:stylesheet>

这里有一种方法来解决,只需计算具有相同id属性的location父元素的前address

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="location/address">
  <xsl:copy>
    <xsl:attribute name="addressId">
      <xsl:value-of select="count(preceding::address[../@id = current()/../@id]) + 1"/>
    </xsl:attribute>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>
</xsl:stylesheet>

重新<xsl:number>:为了在每个位置/@id更改时重新启动它,您可以指定:

<xsl:number from="location[@id!=preceding-sibling::location[1]/@id]" level="any" />

请注意,这与计算具有相同父属性的前面的项目不同;如果将另一个位置的 @id=1 附加到当前列表中,差异将变得明显。

相关内容

  • 没有找到相关文章

最新更新