0

我有一个带有 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。我正在尝试不同的解决方案,当它们开始有意义时,我会在这里写它们。

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

4

1 回答 1

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 字符串引用的元素作为父(../.)元素。在when的上下文中,变量x表示这个元素。

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

于 2013-06-14T08:42:17.103 回答