我的文字有经文编号。
现在,我想用文字数字分开文本,并将单个数字作为ID给出。
由于我不知道如何从源代码中获取数字,我只是给了它们连续的数字,但如果有可能的话,我希望它们从源中分配它们的实际数字。因此,如果缺少一节经文,则XSLT不会连续计数,而是跳过一个数字。
但除此之外,我遇到了问题,我在开头就得到一个空元素<l n="1"/>
。
我认为我的XSLT在某种程度上匹配<p>
,因此实际的n =“1”变为n =“2”。
我该如何解决?
我的来源:
<root> <p>1 This is 2 a <hi rend="bold">beautiful</hi> example 3 poem 4 for showing! 5 my problem</p> </root>
转换为:
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* |node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/p">
<p>
<xsl:variable name="words" select="tokenize(text(),'(1|2|3|4|5|6|7|8|9|0)')" as="xs:string*"/>
<xsl:for-each select="1 to xs:integer(floor(count($words) div 1))">
<xsl:variable name="vIndex" select="(.)" as="xs:integer"/>
<l><xsl:attribute name="n"
select="position()"/>
<xsl:value-of select="$words[$vIndex]"/>
</l>
</xsl:for-each>
</p>
</xsl:template>
</xsl:stylesheet>
我得到的是:
<root>
<p>
<l n="1"/>
<l n="2"> This is </l>
<l n="3"> a beautiful example </l>
<l n="4"> poem </l>
<l n="5"> for showing </l>
<l n="6"> my problem</l>
</p>
</root>
想要的输出是:
<root>
<p>
<l n="1"> This is </l>
<l n="2"> a <hi rend="bold">beautiful</hi> example </l>
<l n="3"> poem </l>
<l n="4"> for showing! </l>
<l n="5"> my problem</l>
</p>
</root>
编辑:我在我的示例中添加了一个元素。
答案 0 :(得分:0)
tokenize
返回的第一个元素将出现在第一个数字之前(在您的情况下,是一个空字符串)。因此,假设您只想要在第一个数字后面显示的内容,则必须从tokenize
的结果中删除第一个元素(例如,使用remove
函数)。
试试这个:
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* |node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/p">
<p>
<xsl:variable name="tokens" select="tokenize(text(),'(1|2|3|4|5|6|7|8|9|0)')" as="xs:string*"/>
<xsl:variable name="words" select="remove($tokens, 1)" as="xs:string*"/>
<xsl:for-each select="1 to xs:integer(floor(count($words) div 1))">
<xsl:variable name="vIndex" select="(.)" as="xs:integer"/>
<l><xsl:attribute name="n"
select="position()"/>
<xsl:value-of select="$words[$vIndex]"/>
</l>
</xsl:for-each>
</p>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
使用analyze-string
代替tokenize
:
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* |node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/p">
<p>
<xsl:analyze-string select="." regex="([0-9]+)([^0-9]*)">
<xsl:matching-substring>
<l name="{regex-group(1)}">
<xsl:value-of select="regex-group(2)"/>
</l>
</xsl:matching-substring>
</xsl:analyze-string>
</p>
</xsl:template>
</xsl:stylesheet>
如果您希望p
元素具有元素子元素,则需要更复杂的方法:
<xsl:stylesheet version="2.0" exclude-result-prefixes="xs"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node() | @*" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@* |node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root/p">
<p>
<xsl:variable name="children">
<xsl:apply-templates select="node()" mode="wrap-number"/>
</xsl:variable>
<xsl:for-each-group select="$children/node()" group-starting-with="n">
<l n="{.}">
<xsl:apply-templates select="current-group() except ."/>
</l>
</xsl:for-each-group>
</p>
</xsl:template>
<xsl:template match="p//text()" mode="wrap-number">
<xsl:analyze-string select="." regex="[0-9]+">
<xsl:matching-substring>
<n><xsl:value-of select="."/></n>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
但这只有在确保行的数字包含在p
元素的文本节点子元素中时才有效,如果在元素子元素中也允许它们(例如<p><span>1 This </span>2 is an example.</p>
)那么更多的工作需要。