请检查并建议, 什么应该是正确的代码和idref值应该与图id相同。我正在尝试使用analyze-string但无法做到。
请检查并建议, 什么应该是正确的代码和idref值应该与图id相同。我正在尝试使用analyze-string但无法做到。
输入
<book>
<figure id="ch01fig01">
<label>Figure 01</label>
<figcaption>xxx</figcaption>
</figure>
<p>This is a Figure 01 and this is figure 02</p>
<p>This is a Figure 01 and this is figure 02</p>
<figure id="ch01fig02">
<label>Figure 02</label>
<figcaption>xxx</figcaption>
</figure>
</book>
输出
<book>
<figure id="ch01fig01">
<label>Figure 01</label>
<figcaption>xxx</figcaption>
</figure>
<p>This is a <internal idref="ch01fig01">Figure 01</internal> and this is <internal idref="ch01fig02">Figure 02</internal></p>
<p>This is a <internal idref="ch01fig01">Figure 01</internal> and this is <internal idref="ch01fig02">Figure 02</internal></p>
<figure id="ch01fig02">
<label>Figure 02</label>
<figcaption>xxx</figcaption>
</figure>
</book>
XSLT
<xsl:output indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//text()[not(parent::label)]">
<xsl:analyze-string select="." regex="figure\s+\d+" flags="i">
<xsl:matching-substring>
<internal>
<xsl:attribute name="idref">
<xsl:call-template name="mk">
<xsl:with-param name="mk11" select="."/>
</xsl:call-template>
</xsl:attribute>
<xsl:value-of select="."/>
</internal>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template name="mk">
<xsl:param name="mk11"/>
<xsl:for-each select="//figure">
<xsl:if test="child::label eq $mk11">
<xsl:value-of select="@id"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
答案 0 :(得分:3)
首先考虑使用密钥来查找数字......
<xsl:key name="figures" match="figure" use="lower-case(label)" />
(我在这里使用小写,因为你在文本中有&#34;图02和#34;但是&#34;图02和#34;在标签中)。
你的主要问题是在xsl:matching-substring
内,你不再在你所匹配的原始节点的上下文中,所以你可能会得到一个错误,即&#34;上下文项不是节点&#34;
要解决此问题,请定义一个变量以允许您引用原始文档...
<xsl:variable name="doc" select="/" />
然后使用键获取数字值,你可以这样做......
<xsl:value-of select="key('figures', lower-case($mk11), $doc)/@id" />
因此,这将在原始文档的上下文中查找密钥。
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:key name="figures" match="figure" use="lower-case(label)" />
<xsl:variable name="doc" select="/" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//text()[not(parent::label)]">
<xsl:analyze-string select="." regex="figure\s+\d+" flags="i">
<xsl:matching-substring>
<internal>
<xsl:attribute name="idref">
<xsl:call-template name="mk">
<xsl:with-param name="mk11" select="."/>
</xsl:call-template>
</xsl:attribute>
<xsl:value-of select="."/>
</internal>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template name="mk">
<xsl:param name="mk11"/>
<xsl:value-of select="key('figures', lower-case($mk11), $doc)/@id" />
</xsl:template>
</xsl:stylesheet>
实际上,您可以通过取消命名模板并使用属性值模板来创建idref
属性
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:key name="figures" match="figure" use="lower-case(label)" />
<xsl:variable name="doc" select="/" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//text()[not(parent::label)]">
<xsl:analyze-string select="." regex="figure\s+\d+" flags="i">
<xsl:matching-substring>
<internal idref="{key('figures', lower-case(.), $doc)/@id}">
<xsl:value-of select="."/>
</internal>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
我使用了另一种方式而不是密钥,它也运行良好。下面是代码做了一些更改。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="figs" select="//figure" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()[not(parent::label)]">
<xsl:choose>
<xsl:when test="matches(., 'Figure', 'i')">
<xsl:analyze-string select="." regex="(Figure ([0-9]+))" flags="i">
<xsl:matching-substring>
<xsl:variable name="ids" select="for $ss in $figs
return
if(matches($ss/label, regex-group(1), 'i'))
then $ss/@id
else ()"></xsl:variable>
<internal idref="{$ids[1]}">
<xsl:value-of select="."/>
</internal>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
以下是运行XSLT后的结果。
<?xml version="1.0" encoding="UTF-8"?>
<book>
<figure id="ch01fig01">
<label>Figure 01</label>
<figcaption>xxx</figcaption>
</figure>
<p>This is a <internal idref="ch01fig01">Figure 01</internal> and this is <internal idref="ch01fig02">figure 02</internal>
</p>
<p>This is a <internal idref="ch01fig01">Figure 01</internal> and this is <internal idref="ch01fig02">figure 02</internal>
</p>
<figure id="ch01fig02">
<label>Figure 02</label>
<figcaption>xxx</figcaption>
</figure>
</book>