使用动态查找进行XSLT转换

时间:2015-05-19 12:57:15

标签: xml xslt xslt-2.0

我需要转换看起来像这样的数据。对于每个用户,我需要读取idcode属性,从idcode标记中获取适当的值,并将它们一起输出。用户可以拥有多个逗号分隔的idcodes。用户列表,每次使用ID和ID查找列表都可以任意大。

输入:

<users>
  <user idcode="1">Doug Edmonds</user>
  <user idcode="2">Jay P. Dunn</user>
  <user idcode="4,5">Gerard A. Kriss</user>
  <user idcode="6">Kirk Korista</user>
  <idcode id="1">100</idcode>
  <idcode id="2">254</idcode>
  <idcode id="3">854</idcode>
  <idcode id="4">741</idcode>
  <idcode id="5">965</idcode>
  <idcode id="6">571</idcode>
</users>

期望的输出:

<systemUser>Doug Edmonds</systemUser>
<systemId value="100"/>
<systemUser>Jay P. Dunn</systemUser>
<systemId value="254"/>
<systemUser>Gerard A. Kriss</systemUser>
<systemId value="741"/>
<systemId value="965"/>
<systemUser>Kirk Korista</systemUser>
<systemId value="571"/>

我正在修补的xslt是:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
                xmlns:xhtml="http://www.w3.org/1999/xhtml"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xhtml xsl xs">

    <xsl:output method="xhtml"/>

    <xsl:template match="header">
        <xsl:apply-templates select="users/user" />
    </xsl:template>

    <xsl:template match="user">
        <xsl:variable name="userName" select="."/>
        <xsl:variable name="userId" select="./@idcode"/>
        <user>{$userName}</user>
        <xsl:variable name="tokenizedId" select="tokenize($userId,',')"/>
        <xsl:for-each select="$tokenizedId">
            <xsl:variable name="singleId" select="."/>
            <xsl:variable name="systemId" select="./users/idcode[@id = '{$singleId}']"/>
            <systemId" value="{$systemId}"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

您可以声明一个交叉引用0:255=[0 1 2 3 ... 254 255]的密钥,并将其用作以下内容:

idcode

答案 1 :(得分:0)

当您真正想要./@idcode时,您使用了../@idcode

另请注意,XPath =运算符可用于序列,因此您不需要$singleId

怎么样:

<xsl:stylesheet version="2.0"
                xmlns:xhtml="http://www.w3.org/1999/xhtml"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xhtml xsl xs">

    <xsl:output method="xhtml"/>
    <xsl:strip-space elements="*" />

    <xsl:template match="user">
        <user><xsl:value-of select="." /></user>
        <xsl:apply-templates select="../idcode[@id = tokenize(current()/@idcode, ',')]" mode="systemId" />
    </xsl:template>

    <xsl:template match="idcode" mode="systemId">
        <systemId value="{.}" />
    </xsl:template>

    <xsl:template match="idcode" />
</xsl:stylesheet>

当然,如果您愿意,也可以用for-each表示同样的事情。

<xsl:stylesheet version="2.0"
                xmlns:xhtml="http://www.w3.org/1999/xhtml"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xhtml xsl xs">

    <xsl:output method="xhtml"/>
    <xsl:strip-space elements="*" />

    <xsl:template match="user">
        <user><xsl:value-of select="." /></user>
        <xsl:for-each select="../idcode[@id = tokenize(current()/@idcode, ',')]">
            <systemId value="{.}" />
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="idcode" />
</xsl:stylesheet>