在我的XSLT转换中,我有两个需要用来处理一个节点的分析字符串。它们一个接一个地工作正常,但我不知道如何将它们组合在一起。
XML文档如下所示:
<article>
<title>Article 1</title>
<text><![CDATA[Lorem ipsum dolor sit amet, s consectetur adipiscing elit. Donec lorem diam, eleifend sed mollis id, condimentum in velit.
Sed sit amet erat ac mauris adipiscing elementum. Pellentesque eget quam augue, id faucibus magna.
Ut malesuada arcu eu elit sodales sodales. Morbi tristique porttitor tristique. Praesent eget vulputate dui. Cras ut tortor massa, at faucibus ligula.]]></text>
</article>
这是我的XSLT:
<xsl:template match="/">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Page title</title>
</head>
<body>
<xsl:for-each select="article">
<h1><xsl:value-of select="./title"/></h1>
<!-- This adds paragraphs tags instead of empty lines in the text -->
<xsl:analyze-string select="./text" regex="
">
<xsl:non-matching-substring>
<p>
<xsl:value-of select="." disable-output-escaping="yes"/>
</p>
</xsl:non-matching-substring>
</xsl:analyze-string>
<!-- This is Czech language specific. It looks for ' s ' (or other letter) and changes second space for . So after that it is ' s '. -->
<xsl:analyze-string select="./text" regex="(\s[k/K/s/S/v/V/z/Z]\s)">
<xsl:matching-substring>
<xsl:text> </xsl:text>
<xsl:value-of select="replace(., ' ','')" disable-output-escaping="yes"/>
<xsl:text disable-output-escaping="yes"><![CDATA[ ]]></xsl:text>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</body>
</html>
</xsl:template>
我需要在生成的文本上应用两个分析字符串,因此段落有<p>
个标记,并且在正确的位置添加了
。
我想要的输出如下:
<h1>Article 1</h1>
<p>Lorem ipsum dolor sit amet, s consectetur adipiscing elit. Donec lorem diam, eleifend sed mollis id, condimentum in velit.</p>
<p>Sed sit amet erat ac mauris adipiscing elementum. Pellentesque eget quam augue, id faucibus magna.</p>
<p>Ut malesuada arcu eu elit sodales sodales. Morbi tristique porttitor tristique. Praesent eget vulputate dui. Cras ut tortor massa, at faucibus ligula.</p>
知道怎么做吗?感谢您抽出宝贵时间并试图帮助我。
答案 0 :(得分:3)
此转化:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" encoding="ascii"/>
<xsl:template match="/*/text">
<xsl:analyze-string select=
"replace(., '\ss\s', ' s ')"
regex="
">
<xsl:non-matching-substring>
<p><xsl:sequence select="."/></p>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template match="title">
<h1><xsl:value-of select="."/></h1>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<article>
<title>Article 1</title>
<text><![CDATA[Lorem ipsum dolor sit amet, s consectetur adipiscing elit. Donec lorem diam, eleifend sed mollis id, condimentum in velit.
Sed sit amet erat ac mauris adipiscing elementum. Pellentesque eget quam augue, id faucibus magna.
Ut malesuada arcu eu elit sodales sodales. Morbi tristique porttitor tristique. Praesent eget vulputate dui. Cras ut tortor massa, at faucibus ligula.]]></text>
</article>
会产生想要的正确结果:
<h1>Article 1</h1>
<p>Lorem ipsum dolor sit amet, s consectetur adipiscing elit. Donec lorem diam, eleifend sed mollis id, condimentum in velit.</p>
<p>Sed sit amet erat ac mauris adipiscing elementum. Pellentesque eget quam augue, id faucibus magna.</p>
<p>Ut malesuada arcu eu elit sodales sodales. Morbi tristique porttitor tristique. Praesent eget vulputate dui. Cras ut tortor massa, at faucibus ligula.</p>
注意:不鼓励程序员使用DOE,因为它不是XSLT 2.0的强制功能,并且不保证任何XSLT 2.0处理器都可能支持DOE。要使用的功能是 character maps 。
然后整个转换变为:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"
encoding="ascii" use-character-maps="nbsp"/>
<xsl:character-map name="nbsp">
<xsl:output-character
character=" " string="&nbsp;"/>
</xsl:character-map>
<xsl:template match="/*/text">
<xsl:analyze-string select=
"replace(., '\ss\s', ' s ')"
regex="
">
<xsl:non-matching-substring>
<p><xsl:sequence select="."/></p>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template match="title">
<h1><xsl:value-of select="."/></h1>
</xsl:template>
</xsl:stylesheet>
,当应用于同一个XML文档(上图)时,会生成所需的正确结果:
<h1>Article 1</h1>
<p>Lorem ipsum dolor sit amet, s consectetur adipiscing elit. Donec lorem diam, eleifend sed mollis id, condimentum in velit.</p>
<p>Sed sit amet erat ac mauris adipiscing elementum. Pellentesque eget quam augue, id faucibus magna.</p>
<p>Ut malesuada arcu eu elit sodales sodales. Morbi tristique porttitor tristique. Praesent eget vulputate dui. Cras ut tortor massa, at faucibus ligula.</p>
答案 1 :(得分:3)
以下是我对Dimitre解决方案的调整:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="UTF-8"/>
<xsl:template match="/*/text">
<xsl:for-each select="tokenize( replace(., '\s([kKsSvVzZ])\s', ' $1 '), '\n')">
<p><xsl:value-of select="."/></p>
</xsl:for-each>
</xsl:template>
<xsl:template match="title">
<h1><xsl:value-of select="."/></h1>
</xsl:template>
</xsl:stylesheet>
备注强>
答案 2 :(得分:2)
你还没有说清楚,但我对这个问题的解释是你想使用第二个xsl:analyze-string来处理第一个的输出。您可以通过将第一个的结果放在变量中来实现,但我的建议是将每个xsl:analyze-string调用放在函数体中,并使用函数组合来组合它们。
<xsl:function name="f:one" as="xs:string">
<xsl:param name="in" as="xs:string">
<xsl:analyze-string select="in".../>
</xsl:function>
<xsl:function name="f:two" as="xs:string">
<xsl:param name="in" as="xs:string">
<xsl:analyze-string select="in".../>
</xsl:function>
... select="f:two(f:one(.))"...
但是,在你的情况下它更简单,因为第一个xsl:analyze-string可以使用对replace()的简单调用来完成。