gpt4 book ai didi

xml - XSLT 更新仅给定属性的新值和 XPath 的属性

转载 作者:行者123 更新时间:2023-12-02 02:17:27 25 4
gpt4 key购买 nike

我有一些代码可以比较两个 XML 文档的属性差异(仅更新,而不是新的属性节点),并生成一组指向属性的 XPath 指针以及属性的新值。

设置

例如,给定旧的 XML 和新的 xml:

旧 XML

<EntityA>
<EntityB id="foo1" value="bar1" ignoredbutsave="bazz1"/>
</EntityA>

新 XML

<EntityA>
<EntityB id="foo2" value="bar2"/>
</EntityA>

我的代码将返回

/EntityA/EntityB/@id, foo2
/EntityA/EntityB/@value, bar2

我想生成一个 XSLT,将旧 XML 合并到新 XML 中,以创建以下 XML:

<EntityA>
<EntityB id="foo2" value="bar2" ignoredbutsave="bazz1"/>
</EntityA>

我在 SO 上找到的所有答案都假设对属性名称有一些先验知识。在本例中,我仅获得属性的 XPath 引用,而不是名称本身。我知道我可以解析 XPath 字符串来派生属性名称,但更愿意将这种复杂性排除在代码之外。

我尝试过的

我无法使用 attribute value template因为我需要从旧 XML 中复制 ignoredbutsave 属性。我尝试使用 xsl:param 从 XPath 中选择属性名称并在 xsl:attribute 中使用它,如下所示:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>

<xsl:template match="/EntityA/EntityB/@id">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<xsl:param name="newValue" select="name(/EntityA/EntityB/@id)"/>
<xsl:attribute name="$newValue">newAttributeId</xsl:attribute>
</xsl:copy>
</xsl:template>

<xsl:template match="/EntityA/EntityB/@value">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<xsl:param name="myattrname" select="name(/EntityA/EntityB/@value)"/>
<xsl:attribute name="$myattrname">newAttributeValue</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

但是,这会导致错误属性“name”的值“$myattrname”不是有效的 QName。

所以,问题是给定属性的 XPath 和该属性的新值,如何生成更新该值而不显式引用属性名称的 XSLT?

最佳答案

此 XSLT 转换:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>

<xsl:template match="/EntityA/EntityB/@id">
<xsl:attribute name="{name()}">foo2</xsl:attribute>
</xsl:template>

<xsl:template match="/EntityA/EntityB/@value">
<xsl:attribute name="{name()}">bar2</xsl:attribute>
</xsl:template>
</xsl:stylesheet>

应用于旧的 XML:

<EntityA>
<EntityB id="foo1" value="bar1" ignoredbutsave="bazz1"/>
</EntityA>

生成旧的 XML,并进行所需的属性值替换:

<EntityA>
<EntityB id="foo2" value="bar2" ignoredbutsave="bazz1"/>
</EntityA>

关于xml - XSLT 更新仅给定属性的新值和 XPath 的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19577698/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com