xsl:for-each获取current()节点属性

时间:2014-11-12 17:13:38

标签: xml foreach xslt-1.0

我对xsl:for-each循环有疑问:

我有类似

的东西
<hodeName>
    <nodeChild name='name1'>value</nodeChild>
    <nodeChild name='name2'>value</nodeChild>
    <nodeChild name='name3'/>
</hodeName>

我想循环遍历它们,使用属性名称命名变量并为其赋值。 我正在与像

这样的事情挣扎
<xsl:for-each select="/root/nodeName">
    <json:string name="{current()/@name}"><xsl:value-of select="current()" /></json:string>
</xsl:for-each>

哪个不起作用。它正在分配正确的xsl:value-of。

2 个答案:

答案 0 :(得分:3)

您正在选择/root/nodeName而非/hodeName/nodeChild,因为您建议使用XML。否则它似乎有效。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:json="http://json.org/"
                version="1.0">
   <xsl:template match="/">
     <json:object>
       <xsl:for-each select="/hodeName/nodeChild">
         <json:string name="{current()/@name}"><xsl:value-of select="current()" /></json:string>
       </xsl:for-each>
     </json:object>
   </xsl:template>
</xsl:stylesheet>

此外,除非是唯一的表达方式,否则您不需要指定current()@name相当于current()/@name

答案 1 :(得分:1)

为什么您的方法不起作用

您正在定义要由for-each处理的序列,如下所示:

<xsl:for-each select="/root/nodeName">

但是如果将它与输入XML进行比较,则没有最外层的元素称为root。最外面的元素称为hodeName。也许你认为/root是XSLT中一个特殊的关键字来引用文档的根目录?事实并非如此。 root只是一个普通的XML元素。 /本身,在XPath表达式的开头,表示 root 文档节点


另一种方法是使用多个模板而不是for-each。 “循环”某事是一个与过程语言更相关的概念,而不是像XSLT那样的声明性功能语言。应用模板是 XSLT-onic (也许你知道Python?)的方式。

您确定最外面的元素应该调用hodeName而不是nodeName吗?

<强>样式表

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

   <xsl:output method="xml" indent="yes"/>
   <xsl:strip-space elements="*"/>          

   <xsl:template match="hodeName">
       <json:object>
           <xsl:apply-templates/>
       </json:object>
   </xsl:template>

   <xsl:template match="nodeChild">
       <json:string name="@name">
           <xsl:value-of select="."/>
       </json:string>
   </xsl:template>

</xsl:stylesheet>

XML输出

<?xml version="1.0" encoding="utf-8"?>
<json:object xmlns:json="http://json.org/">
   <json:string name="@name">value</json:string>
   <json:string name="@name">value</json:string>
   <json:string name="@name"/>
</json:object>