我正在使用XSLT 2.0和xpath 2.0。我在编写一个<xsl:value-of select="">
时会遇到段落中的前导段号,同时仍保留段落中的所有元素。例如:
<p>(1) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
对此:
<p>
<b>(1)<b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.
</p>
以下是我的详细代码,部分符合我的需求:
<xsl:template match="p[substring(.,1,1) = '('][string-length(substring-before(.,')')) < 5]">
<xsl:variable name="paragraphnumber">
<xsl:value-of select="substring-after(substring-before(.,')'),'(')"/>
</xsl:variable>
<xsl:variable name="parenthesednumber" select="concat('(',$paragraphnumber,')')"/>
<p>
<b>
<xsl:value-of select="$parenthesednumber"/>
</b>
<xsl:value-of select="translate(.,$parenthesednumber,'')"/>
</p>
</xsl:template>
模板匹配确保我们只匹配以(
开头的段落,而结束)
之后只有5个字符,允许3个字符的段落编号或文字。
我遇到的问题是我可以获取文本的最后一个value-of
,而不是该段中的其他元素。
答案 0 :(得分:1)
我会说,使用单独的模板是一种更好的方法。通过这样做,您可以确保“权力分配”,并更容易查明错误的代码。
下面的样式表通过matches()
在XSLT中使用正则表达式功能:
<xsl:template match="p[matches(./text()[1],'^\([0-9]+\)')]">
上面的模板匹配p
元素,如果它们的第一个文本节点以“(”,后跟一个或多个数字和“)”开头。如果是这种情况,则检索括号中的数字 - 利用substring-before()
总是以搜索字符串的第一个出现为目标的事实(此处:空格)。
<强>样式表强>
编辑:@Erwin Bolwidt建议。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:template match="p[matches(./text()[1],'^\([0-9]+\)')]">
<xsl:copy>
<b>
<xsl:value-of select="substring-before(.,' ')"/>
</b>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="p|i|b|text()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()[matches(.,'^\([0-9]+\)') and parent::p and position() = 1]">
<xsl:value-of select="substring-after(.,' ')"/>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
<?xml version="1.0" encoding="UTF-8"?><p><b>(1)</b>This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
仅举例说明,如果您的输入如下:
<p>(2) Text1 <b/>(1) Text2</p>
括号中的第一个数字应位于b
元素中,第二个数字应保持不变。这是你得到的输出:
<?xml version="1.0" encoding="UTF-8"?><p><b>(2)</b>Text1 <b/>(1) Text2</p>
为什么您的方法不起作用
我假设有这一行:
<xsl:value-of select="translate(.,$parenthesednumber,'')"/>
您打算输出<p>
的剩余内容。但是,您只输出p
元素的文本内容,而不输出其子元素。您需要明确说明它们也应该被处理 - 例如使用apply-templates
。
答案 1 :(得分:1)
我会用这样的东西:
<xsl:template match="p/text()[1]">
<xsl:analyze-string select="." regex="\(\d+\)">
<xsl:matching-substring>
<b><xsl:value-of select="."/></b>
将“p”元素转换为包含第一个文本节点中额外“b”元素的元素。
答案 2 :(得分:0)
我认为最好在具有(n)数字的段落中的第一个文本节点上进行特定匹配,它使您可以自由地使用身份转换来复制/转换其他节点(文本/元素)在该段中。
警告:我手边只有一个XPath / XSLT 1.0处理器,但我相信这里没有任何内容在1.0和2.0之间有所不同。
样式表:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="p/text()[1][substring(.,1,1) = '('][string-length(substring-before(.,')')) < 5]">
<xsl:variable name="paragraphnumber">
<xsl:value-of select="substring-after(substring-before(.,')'),'(')" />
</xsl:variable>
<xsl:variable name="parenthesednumber" select="concat('(',$paragraphnumber,')')" />
<b>
<xsl:value-of select="$parenthesednumber" />
</b>
<xsl:value-of select="translate(.,$parenthesednumber,'')" />
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出:
<p><b>(1)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
答案 3 :(得分:0)
正如Michael Kay建议的那样,你可以做这样的事情
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="p/text()[1]">
<xsl:analyze-string select="." regex="\(.{{1,3}}\)">
<xsl:matching-substring>
<b><xsl:value-of select="."/></b>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
它搜索以“(”开头,以“)”开头的第一个文本节点,里面有1-3个字符。应用于XML输入时:
<root>
<p>(abc4) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
<p>(123) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
<p>(1ab) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
<p>(a1) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
</root>
它产生:
<root>
<p>(abc4) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
<p><b>(123)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
<p><b>(1ab)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
<p><b>(a1)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
</root>