我刚刚开始'玩'XSLT
,我遇到了一个不容易为我解决的问题。
我收到了以下HTML
代码:
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr,...
<ul>
<li>The first entry</li>
<li>The second entry</li>
<li>The third entry</li>
</ul>
sed diam nonumy eirmod...
</p>
我的结果应如下:
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr,...sed diam nonumy eirmod...</p>
<p>The first entry</p>
<p>The second entry</p>
<p>The third entry</p>
我尝试了一个解决方案,其中ul
模板以结束p
开头 - 标签如
<xsl:template match="//p/ul">
<xsl:for-each select="li">
</p>
<xsl:apply-templates/>
<p>
</xsl:for-each>
</xsl:template>
但这不是正确的XSLT方式。另一种方法是使用这种黑客
<xsl:text disable-output-escaping="yes"><![CDATA[</p>]]></xsl:text>
但我不确定是否还有其他更好的解决方案来解决我的问题。
感谢任何帮助!
答案 0 :(得分:0)
这有点粗糙,但你可以试试这个:
<xsl:template match="*[text()]">
<xsl:variable name="text">
<xsl:copy-of select="text()"/>
</xsl:variable>
<xsl:if test="normalize-space($text)">
<p><xsl:value-of select="normalize-space($text)"/></p>
</xsl:if>
<xsl:apply-templates select="*"/>
</xsl:template>
这会将任意节点与文本匹配,但如果您需要限制,则tou可以将其限制为"p[text()] | li[text()]"
。
它首先将文本放在变量中,以便更容易去掉空格。
答案 1 :(得分:0)
我认为您可以简化当前模板以匹配li
。
<xsl:template match="li">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
如果您只希望它与li
后代的p
元素匹配,则可以将匹配更改为p//li
。
除此之外,您还可以拥有一个匹配p
的模板,您首先只选择text()
个节点,嵌入p
标记,然后选择其他元素。< / p>
<xsl:template match="p">
<p>
<xsl:apply-templates select="text()" />
</p>
<xsl:apply-templates select="*" />
</xsl:template>
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="p">
<p>
<xsl:apply-templates select="text()" />
</p>
<xsl:apply-templates select="*" />
</xsl:template>
<xsl:template match="li">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space()" />
</xsl:template>
</xsl:stylesheet>
注意我在text()
上添加了一个匹配以消除空格。
答案 2 :(得分:0)
这就是为什么&#34;玩耍&#34;并不是学习语言的最佳方式。您可能正在做的是阅读一些示例代码并构建自己的心理模型,以及它的工作方式 - 而且心智模型非常错误。最糟糕的是,一旦你掌握了它,就很难重新学习它。您需要获得一本关于XSLT的好书,并阅读基础概念。
您为自己创建的心理模型是样式表中的<p>
是输出<p>
开始标记的指令,而</p>
是输出结束标记的指令。好吧,XSLT不输出标签,它将节点写入结果树,写元素节点是原子操作,它不能分成两个操作,每个操作写半个节点。因此,在样式表中,<p>(content)</p>
是一条指令,它将p
元素写入结果树,并评估(content)
以生成该节点的内容。顺便说一句,这解释了为什么样式表必须是格式良好的XML。
有两种方法可以回答SO问题:&#34;这是怎么做的&#34;和&#34;这是你出错的地方&#34;。 @TimC给了你一个很好的&#34;怎么做&#34;回答所以我不会重复这一点,但我认为你也会受益于&#34;这是你出错的地方&#34;答案。