我有这个输入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做什么,我将非常感激。对不起,如果这看起来像转贴,但我真的卡住了。
非常感谢答案 0 :(得分:0)
与之前的建议类似,它知道需要匹配 br 元素中的 br 元素。
<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>