gpt4 book ai didi

xml - 用 XSLT 替换节点文本?

转载 作者:数据小太阳 更新时间:2023-10-29 02:19:43 28 4
gpt4 key购买 nike

下面是我的XML文件,用来存储数据-

<Locations>
<location>
<place>Newyork</place>
<dt>01-Dec-2011</dt>
</location>
<location>
<place>Berlin</place>
<dt>02-Dec-2011</dt>
</location>
<location>
<place>Tokyo</place>
<dt>04-Dec-2011</dt>
</location>
</Location>

我要实现的是-

我想替换 <dt>标记日期值,如果访问被重新安排。例如-如果柏林的访问日期更改,则存储在 <dt> 中标签,然后如何编辑/替换相同的在 XML 文件中使用 XSLT..?提前致谢 - 约翰

最佳答案

此转换显示如何使用全局参数(此处使用内联元素建模)指定(可能多个)更新:

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

<my:updates>
<update place="Berlin" dt="11-Dec-2011"/>
</my:updates>

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

<xsl:template match=
"location
[place = document('')/*/my:updates/update/@place]
/dt/text()
">
<xsl:value-of select=
"document('')/*/my:updates/update
[@place = current()/../../place]
/@dt
"/>
</xsl:template>
</xsl:stylesheet>

应用于提供的 XML 文档时(已更正以使其格式正确):

<Locations>
<location>
<place>Newyork</place>
<dt>01-Dec-2011</dt>
</location>
<location>
<place>Berlin</place>
<dt>02-Dec-2011</dt>
</location>
<location>
<place>Tokyo</place>
<dt>04-Dec-2011</dt>
</location>
</Locations>

产生了想要的、正确的结果:

<Locations>
<location>
<place>Newyork</place>
<dt>01-Dec-2011</dt>
</location>
<location>
<place>Berlin</place>
<dt>11-Dec-2011</dt>
</location>
<location>
<place>Tokyo</place>
<dt>04-Dec-2011</dt>
</location>
</Locations>

解释:

  1. 身份规则“按原样”复制每个节点。

  2. 只有一个覆盖模板 -- 匹配任何 dt 的文本节点子节点,其 place 兄弟字符串值为相应的 my:updates/update 元素。在此模板中,我们输出相应 my:updates/update 元素的 dt 属性的值。

请注意:在现实世界的转换中,内联 my:updates 元素将更好地替换为外部全局参数。阅读 XSLT 处理器的文档,了解如何将外部参数传递给转换——这取决于实现。

更新:由于 OP 发现很难将此解决方案转换为使用全局的、外部传递的 xsl:param 的解决方案,这里是此转换后的解决方案:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="pUpdates">
<update place="Berlin" dt="11-Dec-2011"/>
</xsl:param>

<xsl:variable name="vUpdates" select=
"ext:node-set($pUpdates)/*"/>

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

<xsl:template match="dt/text()">
<xsl:choose>
<xsl:when test="../../place=$vUpdates/@place">
<xsl:value-of select=
"$vUpdates[@place = current()/../../place]/@dt"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

当此转换应用于相同的 XML 文档时(如上),会产生相同的正确且想要的结果:

<Locations>
<location>
<place>Newyork</place>
<dt>01-Dec-2011</dt>
</location>
<location>
<place>Berlin</place>
<dt>11-Dec-2011</dt>
</location>
<location>
<place>Tokyo</place>
<dt>04-Dec-2011</dt>
</location>
</Locations>

请注意:在此解决方案中,xsl:param 的值仍然是硬编码的,这是我们使用 ext:node-set 的唯一原因() 扩展函数。如果参数确实是从外部传递过来的,那么这种从RTF到普通树的转换就没有必要了,应该直接引用参数。

此外,在 XSLT 1.0 中,我们必须更加不精确地匹配,并在模板主体内使用比较(xsl:choose)。这是因为在 XSLT 1.0 中不允许在匹配模式中引用变量/参数。

在 XSLT 2.0 中,这个限制已被消除,因此我们可以进行更简单的转换:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="pUpdates">
<update place="Berlin" dt="11-Dec-2011"/>
</xsl:param>

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

<xsl:template match=
"location[place=$pUpdates/*/@place]/dt/text()">
<xsl:value-of select=
"$pUpdates/*[@place = current()/../../place]/@dt"/>
</xsl:template>
</xsl:stylesheet>

关于xml - 用 XSLT 替换节点文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8006946/

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