用 XSLT 替换节点文本?

2023-12-24

下面是我的 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 whose place兄弟的字符串值有一个对应的my:updates/update元素。在此模板中,我们输出的值dt这个对应的属性my:updates/update元素。

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

UPDATE:由于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>

Do note:在此解决方案中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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用 XSLT 替换节点文本? 的相关文章

随机推荐