如何在XSLT 1.0中循环访问IDREFS值?

How to iterate over IDREFS values in XSLT 1.0?

提问人:Melanie 提问时间:7/24/2015 最后编辑:Melanie 更新时间:6/8/2021 访问量:1039

问:

我有一个使用 IDREFS 字段的 xml。我需要提取这些 id 以将它们放在自己的元素中。

这是我认为我需要的基本结构,但我不知道在选择函数中使用什么。

<xsl:template match="node_With_IDREFS_field">
   <xsl:for-each select="EACH ID IN @idrefsField">
      <xsl:element name="newElement">
        <xsl:attribute name="ref"><xsl:value-of select="THE IDREF"/></xsl:attribute>
      </xsl:element>
   </xsl:for-each>
   <!-- keep rest of content -->
   <xsl:apply-templates select="@*|node()"/>
</xsl:template>

所以从这个节点

<node_With_IDREFS_field idrefsField="id1 id2"/>

结果将是

<node_With_IDREFS_field>
  <newElement ref="id1"/>
  <newElement ref="id2"/>
</node_With_IDREFS_field>

感谢您的帮助。

XML XSLT XSLT-1.0

评论

0赞 michael.hor257k 7/24/2015
请向我们展示您的输入示例。
0赞 Melanie 7/24/2015
刚刚做到了!可能是在你输入评论的时候写的!

答:

3赞 michael.hor257k 7/24/2015 #1

您需要对属性的值进行标记化。XSLT 1.0 没有本机 tokenize() 函数,因此您需要调用递归命名模板来执行此操作:idrefsField

<xsl:template match="node_With_IDREFS_field">
    <xsl:copy>
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="@idrefsField"/>
        </xsl:call-template>
    </xsl:copy>
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="' '"/>
    <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
        <xsl:if test="$token">
            <newElement ref="{$token}"/>
        </xsl:if>
        <xsl:if test="contains($text, $delimiter)">
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
            </xsl:call-template>
        </xsl:if>
</xsl:template>

或者,如果您的处理器支持它,则可以使用 EXSLT str:tokenize() 扩展函数。

评论

0赞 Melanie 7/24/2015
如果我想将newElement的实际名称作为参数传递,我该怎么做?我在模板中添加了 <xsl:with-param name=“elementName” select=“'myname'”/>,参数声明,然后添加了 <{$elementName} sentryRef=“{$token}”/>但它不起作用。
0赞 michael.hor257k 7/24/2015
您需要使用 xsl:element 指令才能创建具有计算名称的元素,例如 .<xsl:element name="$elementName"/>
0赞 Melanie 7/24/2015
我确实尝试过,但结果是我得到的一个空节点<xsl:element name="$elementName"><xsl:attribute name="ref"><xsl:value-of select="$token"/></xsl:attribute></xsl:element><node_With_IDREFS_field/>
0赞 Melanie 7/29/2015
哦,我错过了 {} $elementName!
0赞 Deepak Thapa 6/8/2021 #2

你可以试试这个:

<xsl:template match="node_With_IDREFS_field">
    <xsl:element name="node_With_IDREFS_field">
        <xsl:for-each select="tokenize(@idrefsField,' ')">
            <xsl:element name="newElement">
                <xsl:attribute name="ref">
                    <xsl:value-of select="."/>
                </xsl:attribute>
            </xsl:element>
        </xsl:for-each>
    </xsl:element>
</xsl:template>

评论

1赞 michael.hor257k 6/8/2021
这个问题是关于 XSLT 1.0 的。您的答案需要 XSLT 2.0 或更高版本。