代码之家  ›  专栏  ›  技术社区  ›  Milhous

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

  •  3
  • Milhous  · 技术社区  · 5 年前

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

    样本输入:

    <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 回复  |  直到 14 年前
        1
  •  4
  •   Dimitre Novatchev    14 年前

    这种转变 :

    <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>
    
        2
  •  2
  •   Tomalak    14 年前

    <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>