将<span>标记添加到自定义自关闭标记之间的所有文本节点</span>

时间:2010-04-21 18:42:18

标签: xml xhtml xslt-2.0 xslt

我在xhtml中的命名空间x中定义了一对自定义自关闭标记s1和s2。对于具有相同id的每个标记对s1,s2,我想将span标记添加到它们之间的所有文本节点。每个s1,s2标签对都有唯一的ID。我正在寻找基于XSL的解决方案。我正在使用Saxon java处理器进行XSL。

示例输入:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>This is my title</title> 
</head> 
<body> 
<h1 align="center"> 
  This is my heading 
</h1> 
<p> 
  Sample content Some text here. Some content here. 
</p> 
<p> 
   Here you go. 
</p> 
</body> 
</html> 

示例输出:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>This is my title</title> 
</head> 
<body> 
<h1 align="center"> 
  This <span class="spanClass" id="1">is my</span>heading 
</h1> 
<p> 
  Sample content <span class="spanClass" id="2">Some text here. Some content here.</span> 
</p> 
<p> 
   <span class="spanClass" id="3">Here you</span>go. 
</p> 
</body> 
</html> 

2 个答案:

答案 0 :(得分:4)

此转化

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

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

 <xsl:template match="text()[(preceding::s1 | preceding::s2)[last()][self::s1]]">
  <span class="spanClass" id="{generate-id()}">
   <xsl:copy-of select="."/>
  </span>
 </xsl:template>

 <xsl:template match="s1|s2"/>
</xsl:stylesheet>

应用于原始XML文档(更正为格式良好):

<a>
  <b>Some <s1 id="1" />text here</b>
  <c>Some <s2 id="1"/>more text <s1 id="2"/> here</c>
  <d>More data</d>
  <e>Some <s2 id="2" />more data</e>
</a>

生成所需的输出:

<a>
  <b>Some <span class="spanClass" id="IDANI2QB">text here</span></b><span class="spanClass" id="IDAOI2QB">
  </span><c><span class="spanClass" id="IDAQI2QB">Some </span>more text <span class="spanClass" id="IDAWI2QB"> here</span></c><span class="spanClass" id="IDAXI2QB">
  </span><d><span class="spanClass" id="IDAYI2QBIDAYI2QB">More data</span></d><span class="spanClass" id="IDAZI2QB">
  </span><e><span class="spanClass" id="IDA1I2QB">Some </span>more data</e>
</a>

答案 1 :(得分:2)

编辑:修改了使用您添加的XHTML示例的答案。

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:x="http://www.w3.org/1999/xhtml" 
  xmlns="http://www.w3.org/1999/xhtml" 
  exclude-result-prefixes="x"
>
  <xsl:output method="xml" omit-xml-declaration="yes" encoding="utf-8" />

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

  <xsl:template match="text()[normalize-space()]">
    <xsl:choose>
      <xsl:when test="preceding::x:s1[1][
        not(following::x:s2[1][
          following::text()[generate-id() = generate-id(current())]
        ])
      ]">
        <span class="spanClass" id="{generate-id()}">
          <xsl:copy-of select="." />
        </span>
      </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="." />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="x:s1|x:s2" />

</xsl:stylesheet>

结果(换行符/换行符):

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>This is my title</title>
  </head>
  <body>
    <h1 align="center">
      This <span class="spanClass" id="IDATA2Q">is my</span>heading
    </h1>
    <p>
      Sample content <span class="spanClass" id="IDA2A2Q">Some text here. Some content here.</span>
    </p>
    <p>
       <span class="spanClass" id="IDA5A2Q">Here you</span>go.
    </p>
  </body>
</html>