使用xpath获取节点的文本和元素节点子节点

时间:2013-03-26 14:36:49

标签: xslt xpath

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

<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>的{​​{1}},并且文本应该具有相同的格式。

<a>

2 个答案:

答案 0 :(得分: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处理器都可能总是使用它输出的所有元素中的一个或另一个。

答案 1 :(得分: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. identity rule 复制为其执行选择的每个节点,“按原样”。

  2. 使用 AVT (属性值模板)无需xsl:attribute