我有如下XML:
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="paragraph"/>
</w:pPr>
<w:r><w:t>1274394 The milk costs , $1.99 [12] test Figure 1</w:t></w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="paragraph"/>
</w:pPr>
<w:r><w:t>sample text Figure 1 and [1]</w:t></w:r>
</w:p>
</w:body>
我想通过XSLT:获得如下输出
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="paragraph"/>
</w:pPr>
<w:r><w:t>1274394 The milk costs , $1.99 <ref>[12]</ref> test <fig>Figure 1</fig></w:t></w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="paragraph"/>
</w:pPr>
<w:r><w:t>sample text <fig>Figure 1</fig> and <ref>[1]</ref></w:t></w:r>
</w:p>
</w:body>
我的XSLT是:
<xsl:template match="w:p[w:pPr/w:pStyle/@w:val='paragraph']//text()">
<xsl:param name="figregex">
<xsl:text>(Figure)p{Zs}([0-9]{1,2})</xsl:text>
</xsl:param>
<xsl:param name="matchedRegex">
<xsl:text>([)([0-9]{1,2})(])</xsl:text>
</xsl:param>
<xsl:variable name="fig-first" select=""<fig>""/>
<xsl:variable name="fig-sec" select=""</fig>""/>
<xsl:variable name="r-first" select=""<ref>""/>
<xsl:variable name="r-sec" select=""</ref>""/>
<xsl:analyze-string select="." regex="{$matchedRegex} | {$figregex} ">
<xsl:matching-substring>
<xsl:if test="matches(., $figregex)" >
<xsl:value-of select="$fig-first" disable-output-escaping="yes"/><xsl:value-of select="."/>
<xsl:value-of select="$fig-sec" disable-output-escaping="yes"/>
</xsl:if>
<xsl:if test="matches(., $matchedRegex)" >
<xsl:value-of select="$r-first" disable-output-escaping="yes"/><xsl:value-of select="."/>
<xsl:value-of select="$r-sec" disable-output-escaping="yes"/>
</xsl:if>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
它运行良好,但如果两者都在同一行,则前面的一个首先被转换。有人能帮我吗?我得到的输出是:
<w:body>
<w:p>
<w:pPr>
<w:pStyle w:val="paragraph"/>
</w:pPr>
<w:r><w:t>1274394 The milk costs , $1.99 <ref>[12] </ref>test Figure 1</w:t></w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="paragraph"/>
</w:pPr>
<w:r><w:t>sample text<fig> Figure 1 </fig>and [1]</w:t></w:r>
</w:p>
</w:body>
这个XSLT 2.0样式表
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:w="www"
exclude-result-prefixes='xsl fn'>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="w:t/text()">
<xsl:variable name="phase1">
<xsl:apply-templates select="." mode="fig" />
</xsl:variable>
<xsl:apply-templates select="$phase1" mode="ref" />
</xsl:template>
<xsl:template match="text()" mode="fig">
<xsl:analyze-string select="." regex="Figure (d{{1,2}})">
<xsl:matching-substring>
<fig>
<xsl:value-of select="." />
</fig>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="." />
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template match="text()" mode="ref">
<xsl:analyze-string select="." regex="[(d{{1,2}})]">
<xsl:matching-substring>
<ref>
<xsl:value-of select="." />
</ref>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="." />
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template match="@*|*|comment()|processing-instruction()" mode="ref">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="ref"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
。。。将样本输入转换为
<w:body xmlns:w="www">
<w:p>
<w:pPr>
<w:pStyle w:val="paragraph"/>
</w:pPr>
<w:r>
<w:t>1274394 The milk costs , $1.99 <ref>[12]</ref> test <fig>Figure 1</fig>
</w:t>
</w:r>
</w:p>
<w:p>
<w:pPr>
<w:pStyle w:val="paragraph"/>
</w:pPr>
<w:r>
<w:t>sample text <fig>Figure 1</fig> and <ref>[1]</ref>
</w:t>
</w:r>
</w:p>
</w:body>
备注
- 此样式表使用管线设计。第一阶段("ig")处理Figure模式,第二阶段("ef")处理ref模式
- 这不是唯一好的解决方案。使用通用命名模板而不是ref和fig模式模板是非常可行的,甚至可能更严格。其他一些Stackie可能会接受挑战,展示一个更简单的一次性解决方案
- 除非您真的需要,否则尽量不要使用禁用输出转义。这样做会浪费XSLT的很多功能。这类似于使用SQL表达式生成数据集,但随后使用一些汇编代码来计算其中一个列输出
- 使用文字正则表达式时,请记住对curlies进行双转义