Xslt 用p标签替换br标签问题

Xslt 用p标签替换br标签问题,xslt,Xslt,我有这个输入xml <body> <p class="heading"> <span><tag>This text</tag> <br/> </span> </p> <p class="bodyText"> <span><tag>is</tag> <br/> </span> <span><tag>mea

我有这个输入xml

<body>

<p class="heading">
<span><tag>This text</tag>
<br/>
</span>
</p>

<p class="bodyText">
<span><tag>is</tag>
<br/>
</span>
<span><tag>meant</tag>
</span>
<span><tag>to</tag>
<br/>
</span>
</p>

<p class="bodyText">
<span>
<tag>be</tag></span>
<span>
<tag>read</tag>
<br/>
</span>
<span><tag>with</tag></span>
<span><tag>some</tag></span>
<span><tag>inline</tag><br/></span>
<span class="italic">
<tag>styles</tag>
<br/>
<tag>the</tag>
<br/>
<tag>end</tag>
</span>
</p>

</body>

本文


意味 到

是 阅读
具有 一些 内联
风格
这个
结束

我希望得到这个输出-用p标记替换br标记并继承所有/任何类

<body>

<p class="heading">
<span>
<tag>This text</tag>
</span>
</p>

<p class="bodyText">
<span>
<tag>is</tag>
</span>
</p>

<p class="bodyText">
<span>
<tag>meant</tag>
</span>
<span>
<tag>to</tag>
</span>
</p>

<p class="bodyText">
<span>
<tag>be</tag>
</span>
<span>
<tag>read</tag>
</span>
</p>

<p class="bodyText">
<span>
<tag>with</tag>
</span>
<span>
<tag>some</tag>
</span>
<span>
<tag>inline</tag>
</span>
</p>

<p class="bodyText">
<span class="italic">
<tag>styles</tag>
</span>
</p>

<p class="bodyText">
<span class="italic">
<tag>the</tag>
</span>
</p>

<p class="bodyText">
<span class="italic">
<tag>end</tag>
</span>
</p>

</body>

本文

意味 到

是 阅读

具有 一些 内联

风格

这个

结束

XSLT:到目前为止,已经提出了一些很好的建议(尽管使用了更简单的XML输入)

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="p">
<xsl:apply-templates select="span[1]" mode="group"/>
</xsl:template>

<xsl:template match="span[not(br)]" mode="group">
    <p>
<xsl:apply-templates select="."/>
</p>
<xsl:apply-templates select="following-sibling::span[br][1]/following-  sibling::span[1]" mode="group"/>
</xsl:template>

<xsl:template match="span[br]" mode="group">
<p>
<xsl:apply-templates select="."/>
</p>
<xsl:apply-templates select="following-sibling::span[1]" mode="group"/>
</xsl:template>


<xsl:template match="span[not(br)]">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::span[1]"/>
</xsl:template>

<xsl:template match="span/br"/>

</xsl:stylesheet>


在输入的最后一个span标记中的最后一组br之前,它一直起作用。我也有一个很好的建议,这个建议也是一样的,但是使用了一把钥匙

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>

<xsl:key name="para" match="span" use="generate-id(following-sibling::br[1])" />

<xsl:template match="/">
<body>
<xsl:apply-templates select="body/p" />
</body>
</xsl:template>

<xsl:template match="p">
<xsl:apply-templates select="br" />
<xsl:if test="span[not(following-sibling::br)]">
<p>
<xsl:apply-templates select="span[not(following-sibling::br)]" />
</p>
</xsl:if>
</xsl:template>

<xsl:template match="br">
<p>
<xsl:apply-templates select="key('para', generate-id())" />
</p>
</xsl:template>

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

</xsl:stylesheet>


…还是同一个问题。如果有人能指出我需要如何处理XSLT的任何一部分,我将不胜感激。抱歉,如果这看起来像是一个转载,但我真的卡住了


非常感谢

与前面的建议类似,它知道需要匹配br元素中的span元素

<xsl:key name="para" match="span[not(br)]" 
  use="generate-id(following-sibling::span[br])"/>

因此,这将把所有跨度组合在一起,而不使用br

但是也需要查找span标记中有多个br元素的情况

<xsl:key name="br" match="tag" 
  use="generate-id(preceding-sibling::br[1])"/>

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="para" match="span[not(br)]" use="generate-id(following-sibling::span[br])"/>
   <xsl:key name="br" match="tag" use="generate-id(preceding-sibling::br[1])"/>

   <xsl:template match="/">
      <body>
         <xsl:apply-templates select="body/p"/>
      </body>
   </xsl:template>

   <!-- Start by matching p tags -->
   <xsl:template match="p">
      <xsl:apply-templates select="span[br]"/>
   </xsl:template>

   <!-- Match the span tags with br tags present -->
   <xsl:template match="span[br]">
      <p>
         <!-- Get attributes for p tag -->
         <xsl:apply-templates select="../@*" />

         <!-- Copy all prior span tags without br elements -->
         <xsl:apply-templates select="key('para', generate-id())"/>

         <!-- Copy the elements for this span up to any br tag -->
         <xsl:copy>
            <xsl:apply-templates select="@*|node()[not(preceding-sibling::br)]"/>
         </xsl:copy>
      </p>

      <!-- Special case for span tags containing multiple br tags -->
      <xsl:apply-templates select="br[following-sibling::*]" mode="special" />
   </xsl:template>

   <!-- Ignore br tags normally -->
   <xsl:template match="br" />

   <!-- In the special case, need to group elements following the br tag -->
   <xsl:template match="br" mode="special">
      <p>
         <!-- Copy the attributes for current p tag -->
         <xsl:apply-templates select="../../@*" />
         <span>
            <!-- Copy the attributes for current span tag -->
            <xsl:apply-templates select="../@*" />

            <!-- List all elements following the br tag -->
            <xsl:apply-templates select="key('br', generate-id())"/>
         </span>
      </p>
   </xsl:template>

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


应用于输入示例时,以下为输出

<body>
   <p class="heading">
      <span>
         <tag>This text</tag>
      </span>
   </p>
   <p class="bodyText">
      <span>
         <tag>is</tag>
      </span>
   </p>
   <p class="bodyText">
      <span>
         <tag>meant</tag>
      </span>
      <span>
         <tag>to</tag>
      </span>
   </p>
   <p class="bodyText">
      <span>
         <tag>be</tag>
      </span>
      <span>
         <tag>read</tag>
      </span>
   </p>
   <p class="bodyText">
      <span>
         <tag>with</tag>
      </span>
      <span>
         <tag>some</tag>
      </span>
      <span>
         <tag>inline</tag>
      </span>
   </p>
   <p class="bodyText">
      <span class="italic">
         <tag>styles</tag>
      </span>
   </p>
   <p class="bodyText">
      <span class="italic">
         <tag>the</tag>
      </span>
   </p>
   <p class="bodyText">
      <span class="italic">
         <tag>end</tag>
      </span>
   </p>
</body>

本文

意味 到

是 阅读

具有 一些 内联

风格

这个

结束


与前面的建议类似,它知道需要匹配br元素中的span元素

<xsl:key name="para" match="span[not(br)]" 
  use="generate-id(following-sibling::span[br])"/>

因此,这将把所有跨度组合在一起,而不使用br

但是也需要查找span标记中有多个br元素的情况

<xsl:key name="br" match="tag" 
  use="generate-id(preceding-sibling::br[1])"/>

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="para" match="span[not(br)]" use="generate-id(following-sibling::span[br])"/>
   <xsl:key name="br" match="tag" use="generate-id(preceding-sibling::br[1])"/>

   <xsl:template match="/">
      <body>
         <xsl:apply-templates select="body/p"/>
      </body>
   </xsl:template>

   <!-- Start by matching p tags -->
   <xsl:template match="p">
      <xsl:apply-templates select="span[br]"/>
   </xsl:template>

   <!-- Match the span tags with br tags present -->
   <xsl:template match="span[br]">
      <p>
         <!-- Get attributes for p tag -->
         <xsl:apply-templates select="../@*" />

         <!-- Copy all prior span tags without br elements -->
         <xsl:apply-templates select="key('para', generate-id())"/>

         <!-- Copy the elements for this span up to any br tag -->
         <xsl:copy>
            <xsl:apply-templates select="@*|node()[not(preceding-sibling::br)]"/>
         </xsl:copy>
      </p>

      <!-- Special case for span tags containing multiple br tags -->
      <xsl:apply-templates select="br[following-sibling::*]" mode="special" />
   </xsl:template>

   <!-- Ignore br tags normally -->
   <xsl:template match="br" />

   <!-- In the special case, need to group elements following the br tag -->
   <xsl:template match="br" mode="special">
      <p>
         <!-- Copy the attributes for current p tag -->
         <xsl:apply-templates select="../../@*" />
         <span>
            <!-- Copy the attributes for current span tag -->
            <xsl:apply-templates select="../@*" />

            <!-- List all elements following the br tag -->
            <xsl:apply-templates select="key('br', generate-id())"/>
         </span>
      </p>
   </xsl:template>

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


应用于输入示例时,以下为输出

<body>
   <p class="heading">
      <span>
         <tag>This text</tag>
      </span>
   </p>
   <p class="bodyText">
      <span>
         <tag>is</tag>
      </span>
   </p>
   <p class="bodyText">
      <span>
         <tag>meant</tag>
      </span>
      <span>
         <tag>to</tag>
      </span>
   </p>
   <p class="bodyText">
      <span>
         <tag>be</tag>
      </span>
      <span>
         <tag>read</tag>
      </span>
   </p>
   <p class="bodyText">
      <span>
         <tag>with</tag>
      </span>
      <span>
         <tag>some</tag>
      </span>
      <span>
         <tag>inline</tag>
      </span>
   </p>
   <p class="bodyText">
      <span class="italic">
         <tag>styles</tag>
      </span>
   </p>
   <p class="bodyText">
      <span class="italic">
         <tag>the</tag>
      </span>
   </p>
   <p class="bodyText">
      <span class="italic">
         <tag>end</tag>
      </span>
   </p>
</body>

本文

意味 到

是 阅读

具有 一些 内联

风格

这个

结束