当前位置: 首页 > 知识库问答 >
问题:

XSLT:递归连接父节点属性值和子节点属性值

皇甫卓君
2023-03-14

我想递归地连接一个节点的参数值和它的父节点的相同参数值。

例如,如下:

<node name="root">
  <node name="A">
    <node name="B">
      <node name="C">
        <value1>12</value1>
        <value2>36</value1>
      </node>
    </node>
  </node>
</node>

应该成为

<node name="root">
  <node name="root.A">
    <node name="root.A.B">
      <node name="root.A.B.C">
        <value1>12</value1>
        <value2>36</value1>
      </node>
    </node>
  </node>
</node>

我试过了

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="node/@name">
  <xsl:choose>
    <xsl:when test=". = 'root'">
      <xsl:attribute name="name"><xsl:text>webshop</xsl:text></xsl:attribute>
    </xsl:when>
    <xsl:when test="not(. = 'root')">
      <xsl:attribute name="name"><xsl:value-of select="../../@name"/>.<xsl:value-of select="../@name"/></xsl:attribute>
    </xsl:when>
  </xsl:choose>
</xsl:template>
<node name="root">
  <node name="root.A">
    <node name="A.B">
      <node name="B.C">
        <value1>12</value1>
        <value2>36</value1>
      </node>
    </node>
  </node>
</node>

有什么问题吗?

共有1个答案

王长卿
2023-03-14

XSLT对输入文档进行操作以生成新的输出文档。输入文档本身将保持不变。当您执行xsl: value-of(或任何其他XSLT操作)时,您将从输入文档中进行选择。因此,您向name属性添加值的事实根本不会影响您的xsl: value-of语句。

您可以使用一个简单的xsl:for each来获取所有祖先节点,并从中构建name属性:

<xsl:for-each select="ancestor::node">
  <xsl:if test="position() > 1">.</xsl:if>
  <xsl:value-of select="@name" />
</xsl:for-each>

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node/@name">
    <xsl:attribute name="name">
      <xsl:choose>
        <xsl:when test=". = 'root'">webshop</xsl:when>
        <xsl:otherwise>
          <xsl:for-each select="ancestor::node">
            <xsl:if test="position() > 1">.</xsl:if>
            <xsl:value-of select="@name" />
          </xsl:for-each>
       </xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

如果可以使用XSLT2.0,则可以使用单个xsl:value

<xsl:value-of select="ancestor::node/@name" separator="." />

(在XSLT1.0中,xsl:value of仅输出集合中的第一个节点)

 类似资料:
  • 问题内容: 我正在尝试读取xml文件,例如: 这是我到目前为止的代码: 这是我尝试编写此代码的尝试,怎么说都不成功,这就是我开始赏金的原因。这是http://pastebin.com/huKP4KED。 赏金更新: 我确实真的尝试了好几天,但现在没想到会这么难,我会接受有用的链接/书籍/教程,但更喜欢代码,因为我昨天需要这样做。 这是我需要的: 关于上面的xml: 我需要获取标题ID的值 temp

  • 对于下面的XML,我正在尝试根据属性和节点值提取节点。 基于属性class=pass和h1包含('objectives'),我试图提取以下输出。 “目标”是节点值字符串“1任务目标”的一部分 1任务目标1目标2 下面是我正在尝试的XPath表达式。然而,这并没有产生任何输出。你能指出我做错了什么吗? 谢谢

  • 我很难使用下面的用例。 以下是XML: 我想要实现的是基于节点

  • 主要内容:节点锚点,节点标签,节点内容每个表示节点包括两个主要特征,称为锚和标记。可以使用节点内容指定节点属性,从字符流中省略。 节点表示的基本示例如下 - 节点锚点 属性表示将来参考的节点。 节点中YAML表示的字符流用符号表示。 YAML处理器不需要保留锚名称以及其中包含的表示细节。以下代码解释了这一点 - 锚节点生成的YAML输出如下所示 - 节点标签 属性表示完全定义节点的本机数据结构的类型。 标签用()指示符表示。 标签被视

  • 我有一个XML: 我想向根元素:/doc添加一个属性(名称空间),以便输出如下所示: 我尝试了三种xslt(跳过了默认的“复制所有”部分以减少问题的长度)。 xslt1:见下文,问题在于将空名称空间xmlns=”“添加到/doc的所有子节点(即:/doc/tag1和/doc/tag2) Xslt2:见下文,问题是“ns”被添加到根节点:和 xslt3:请参见下文,问题是报告了错误:未定义名称空间前

  • 我想从父节点复制到子节点。我真的不确定这是如何实现的。 我的源xml 我想得到输出为 我想要XSLT1.0中的解决方案。 我想将这些节点复制到子节点 谢谢。