更改动态XPath标识的元素的文本

时间:2013-06-13 13:57:43

标签: xslt xpath xalan

我有一个带有2个XML片段的XML,第一个是必须应用新值的片段(可能有非常复杂的元素),如

... some static parents
<a:element1>
   <a:subelement tag="someString">
      <a:s1>a</a:s1>
   </a:subelement>
</a:element1>
<a:element2>b</a:element2>
<a:element3>c</a:element3>
... lots of other elements like the above ones

和第二个片段,它具有从第一个XML生成的XPath和一个新值,如

<field>
   <xpath>/Parent/element1/subelement[@tag="someString"]/s1</xpath>
   <newValue>1</newValue>
</field>
<field>
   <xpath>/Parent/element2</xpath>
   <newValue>2</newValue>
</field>

我们可能没有新值来申请第一个片段中的所有元素。

我正在努力进行XSLT转换,应该将新值应用于XPath指示的位置。

输出应为:

... some static parents
<a:element1>
   <a:subelement tag="someString">
      <a:s1>1</a:s1>
   </a:subelement>
</a:element1>
<a:element2>2</a:element2>
... lots of other elements like the above ones

我可以访问xalan:evaluate来评估动态xpath。我正在尝试不同的解决方案,当他们开始有意义时,我会在这里写下来。

任何方法的想法都很受欢迎。感谢

1 个答案:

答案 0 :(得分:0)

Oki,我发现了如何,我会在这里写下答案,也许某人有时会需要这个:

<xsl:template match="/">

<!-- static parents -->
  <a:Root>
    <xsl:apply-templates select="/a:Root/a:Parent" />
  </a:Root>

</xsl:template>

<xsl:template match="@*|*|text()">

<xsl:variable name="x" select="generate-id(../.)" />
<xsl:variable name="y" select="//field[generate-id(xalan:evaluate(xpath)) = $x]" />

<xsl:choose>
  <xsl:when test="$y">
    <xsl:value-of select="$y/newValue" />
  </xsl:when>
  <xsl:otherwise>
    <xsl:copy>
        <xsl:apply-templates select="@*|*|text()" />
    </xsl:copy>
  </xsl:otherwise>
</xsl:choose>

</xsl:template>

并解释转型: 我正在写下静态的部分,然后在我感兴趣的片段上调用apply-templates,它具有液体结构。

然后我使用稍微修改过的身份转换,将所有内容从源复制到目标(从 / a:Root / a:Parent 片段开始),除非我们将自己置于文本上我有兴趣改变。

我感兴趣的 text()将作为父(../。)在第二个片段中找到的xpath字符串引用的元素。变量 x 表示在 when 的上下文中,此元素。

变量 y 找到字段元素,该元素具有 xpath 元素作为子元素,如果使用 xalan 进行评估,则引用与 x 变量相关的元素。 现在我使用 generate-id()来比较物理元素,否则它将通过元素的 toString 进行比较(这是错误的)。如果变量 y 不存在,则意味着我没有可能已更改的此元素的 xpath 元素,并且我将其保留。如果 y 变量存在,我可以从中获取 newValue ,并且我当前位于要更新的​​文本元素上。