我有一个带有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。我正在尝试不同的解决方案,当他们开始有意义时,我会在这里写下来。
任何方法的想法都很受欢迎。感谢
答案 0 :(得分:0)
<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 ,并且我当前位于要更新的文本元素上。