0

我有一个标签,其中包含标签和文本。

<p>

Hello world <xref rid='1234'>1234</xref> this is a new world starting
<xref rid="5678">5678</xref>
finishing the new world

</p>

我将使用 xslt 对其进行转换,并且在输出中我需要替换<xref>for<a>并且文本应该具有相同的格式。

<p>

Hello world <a href='1234'>1234</a> this is a new world starting
<a href="5678">5678</a>
finishing the new world

</p>
4

2 回答 2

0

XSLT 中处理此类事情的标准方法是使用身份模板将所有内容逐字复制从输入到输出,然后在您想要更改某些内容时使用特定模板覆盖该模板。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <!-- identity template to copy everything as-is unless overridden -->
  <xsl:template match="*@|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
  </xsl:template>

  <!-- replace xref with a -->
  <xsl:template match="xref">
    <a><xsl:apply-templates select="@*|node()" /></a>
  </xsl:template>

  <!-- replace rid with href -->
  <xsl:template match="xref/@rid">
    <xsl:attribute name="href"><xsl:value-of select="." /></xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

如果您知道每个xref元素肯定都有一个rid属性,那么您可以将两个“特定”模板合并为一个。

请注意,没有任何基于 XSLT 的解决方案能够保留这样一个事实,即您的某些输入元素使用单引号作为属性,而其他输入元素使用双引号,因为此信息在 XPath 数据模型中不可用(两种形式完全等同于就 XML 解析器而言)。XSLT 处理器很可能总是对它输出的所有元素使用一种或另一种,而不管输入元素的外观如何。

于 2013-03-26T14:40:43.557 回答
0

解决方案非常简单(只有两个模板):

<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="xref">
   <a href="{@rid}"><xsl:apply-templates/></a>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<p>

Hello world <xref rid='1234'>1234</xref> this is a new world starting
<xref rid="5678">5678</xref>
finishing the new world

</p>

产生了想要的正确结果:

<p>

Hello world <a href="1234">1234</a> this is a new world starting
<a href="5678">5678</a>
finishing the new world

</p>

说明

  1. 身份规则“按原样”复制选择执行的每个节点。

  2. 使用AVT(属性值模板)消除了对xsl:attribute

于 2013-03-26T14:45:52.513 回答