引用不同的兄弟节点

时间:2014-11-20 16:30:27

标签: xml xslt

我如何在xsl中实现这一目标?我曾尝试将其与apply-templates一起使用,但我没有运气。

的test.xml

<row>
    <table name="Person">
        <tuple>
            <val>BOB</val>
            <val>BILL</val>
        </tuple>
    </table>
    <table name="Age">
        <tuple>
            <val>18</val>
            <val>21</val>
        </tuple>
    </table>
</row>

期望的输出

<row>
    <data>
        <name>BOB</name>
        <age>18</age>
    </data>
    <data>
        <name>BILL</name>
        <age>21</age>
    </data>
</row>

2 个答案:

答案 0 :(得分:1)

我不知道用XSL进行解构绑定的任何方法;我有兴趣知道是否有原生成语。

反正:

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

<xsl:template match="/row">
  <row>
  <xsl:for-each select="table[@name='Person']/tuple/val">
    <xsl:variable name="i" select="position()" />
    <data>
      <name><xsl:value-of select="." /></name>
      <age><xsl:value-of select="../../../table[@name='Age']/tuple/val[position()=$i]" /></age>
    </data>
  </xsl:for-each>
  </row>
</xsl:template>

</xsl:stylesheet>

不可否认,那里没有最漂亮的XSL样式表,但它确实可以解决问题。

当然,假设每个名称条目在此处都有匹配的年龄条目。如果你的名字和年龄条目在原始XML文档中被id交叉引用,那将会很有帮助。

答案 1 :(得分:1)

另一种可以实现的方法是使用xsl:key根据位置查找val元素

 <xsl:key name="values" match="val" use="count(preceding-sibling::val)" />

然后,您将遍历第一个val

中的table个元素
<xsl:for-each select="table[1]/tuple/val">

然后,您可以使用密钥获取构成val元素的所有data元素

<xsl:apply-templates select="key('values', position() - 1)" />

唯一真正凌乱的一点是如何映射&#34; Person&#34;的name属性。输出&#34; name&#34;的元素代替。

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:key name="values" match="val" use="count(preceding-sibling::val)" />

    <xsl:template match="/row">
        <row>
            <xsl:for-each select="table[1]/tuple/val">
                <data>
                    <xsl:apply-templates select="key('values', position() - 1)" />
                </data>
            </xsl:for-each>
        </row>
    </xsl:template>

    <xsl:template match="val">
        <xsl:variable name="name">
            <xsl:choose>
                <xsl:when test="../../@name = 'Person'">name</xsl:when>
                <xsl:otherwise><xsl:value-of select="translate(../../@name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" /></xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:element name="{$name}">
            <xsl:value-of select="." />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

除了凌乱的xsl:choose之外,这个解决方案也非常通用。

相关问题