2011-09-19 53 views
2

我有這個輸入XML與p標籤問題更換BR標籤

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

哪些起來,直到輸入的最後一個跨距標籤最後一組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做什麼,我將非常感激。對不起,如果這看起來像一個轉發,但我真的卡住了。

千恩萬謝

回答

0

到以前的建議類似,它知道需要匹配BR元素跨度元素內。

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

所以,這將組合在一起的所有跨越沒有BR

但也需要爲在有多個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>