首页 文章

XSLT标记了一个跨子元素分布的字符串

提问于
浏览
1

我觉得那里有一个明显的解决方案,但我想不出来 . 使用XSLT 2.0我想要标记一个跨子元素分布的字符串,所以就像这样

<line>
    <font style="big">
        <text color="blue">wha</text>
    </font>
    <font style="small">
        <text color="red">t is o</text>
    </font>
    <font style="small">
        <text color="blue">n </text>
    </font>
    <font style="small">
        <text color="blue">his </text>
    </font>
    <font style="small">
        <text color="blue">mind.</text>
    </font>
</line>

我想将字符串的值标记化,即将字符串拆分为空白和标点符号,但仍将每个段保留在其树结构中 . 那么我想要的是:

<line>
    <token>
        <font style="big">
            <text color="blue">wha</text>
        </font>
        <font style="small">
            <text color="red">t</text>
        </font>
    </token>
    <token>
        <font style="small">
            <text color="red">is</text>
        </font>
    </token>
    <token>
        <font style="small">
            <text color="red">o</text>
        </font>
        <font style="small">
            <text color="blue">n</text>
        </font>
    </token>
  <token>
      <font style="small">
          <text color="blue">his</text>
      </font>
  </token>
  <token>
    <font style="small">
        <text color="blue">mind</text>
    </font>
  </token>
  <token>
    <font style="small">
      <text color="blue">.</text>
    </font>
  </token
</line>

I.E.,将每个单词和标点符号移动到单独的标记元素中 . 现在,只需一个字符串,这很简单,我可以使用analyze-string或matches()之一,但我找不到一个优雅而强大的解决方案来完成这项任务 .

我很高兴听到你的想法,Ruprecht

1 回答

  • 2

    这做了一半的工作,标记字符串,它没有添加你的 <token> 标记,就像我正确理解它需要字典查找来识别单词 . 它产生

    <line>
       <font style="big">
          <text color="blue">wha</text>
       </font>
       <font style="small">
          <text color="red">t</text>
       </font>
       <font style="small">
          <text color="red">is</text>
       </font>
       <font style="small">
          <text color="red">o</text>
       </font>
       <font style="small">
          <text color="blue">n</text>
       </font>
       <font style="small">
          <text color="blue">his</text>
       </font>
       <font style="small">
          <text color="blue">mind.</text>
       </font>
    </line>
    

    样式表:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>
    
    <xsl:template match="*">
     <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
     </xsl:copy>
    </xsl:template>
    
    <xsl:template match="font">
     <xsl:variable name="fa" select="@*"/>
     <xsl:for-each select="text">
      <xsl:variable name="ta" select="@*"/>
      <xsl:for-each select="text()/tokenize(.,'\s+')[.]">
       <font>
        <xsl:copy-of select="$fa"/>
        <text>
         <xsl:copy-of select="$ta"/>
         <xsl:value-of select="."/>
        </text>
       </font>
      </xsl:for-each>
     </xsl:for-each>
    </xsl:template>
    
    </xsl:stylesheet>
    

    在评论中澄清之后确定更新,现在生成

    <line>
       <token>
          <font style="big">
             <text color="blue">wha</text>
          </font>
          <font style="small">
             <text color="red">t</text>
          </font>
       </token>
       <token>
          <font style="small">
             <text color="red">is</text>
          </font>
       </token>
       <token>
          <font style="small">
             <text color="red">o</text>
          </font>
          <font style="small">
             <text color="blue">n</text>
          </font>
       </token>
       <token>
          <font style="small">
             <text color="blue">his</text>
          </font>
       </token>
       <token>
          <font style="small">
             <text color="blue">mind</text>
          </font>
       </token>
       <token>
          <font style="small">
             <text color="blue">.</text>
          </font>
       </token>
    </line>
    

    XSLT:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
     <xsl:strip-space elements="*"/>
     <xsl:output indent="yes"/>
    
     <xsl:template match="*">
      <xsl:copy>
       <xsl:copy-of select="@*"/>
       <xsl:apply-templates/>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="*[font]">
      <xsl:copy>
       <xsl:copy-of select="@*"/>
       <xsl:variable name="p1">
        <xsl:apply-templates/>
       </xsl:variable>
       <xsl:for-each-group  select="$p1/*" group-starting-with="tok">
        <token>
         <xsl:copy-of select="current-group() except self::tok"/>
        </token>
       </xsl:for-each-group>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="font">
      <xsl:variable name="fa" select="@*"/>
      <xsl:for-each select="text">
       <xsl:variable name="ta" select="@*"/>
       <xsl:if test="position()=1 and matches(.,'^\s')"><tok/></xsl:if>
       <xsl:for-each select="text()/tokenize(.,'\s+')[.]">
        <xsl:if test="position()!=1"><tok/></xsl:if>
        <xsl:analyze-string regex="[.,;?]" select=".">
         <xsl:matching-substring>
          <tok/>
          <font>
           <xsl:copy-of select="$fa"/>
           <text>
        <xsl:copy-of select="$ta"/>
        <xsl:value-of select="."/>
           </text>
          </font>
         </xsl:matching-substring>
         <xsl:non-matching-substring>
          <font>
           <xsl:copy-of select="$fa"/>
           <text>
        <xsl:copy-of select="$ta"/>
        <xsl:value-of select="."/>
           </text>
          </font>
         </xsl:non-matching-substring>
        </xsl:analyze-string>
       </xsl:for-each>
       <xsl:if test="position()=last() and matches(.,'\s$')"><tok/></xsl:if>
      </xsl:for-each>
     </xsl:template>
    
    </xsl:stylesheet>
    

相关问题