请检查并建议,什么应该是正确的代码和idref值应该与图id相同。我正在尝试使用分析字符串,但做不到。
请检查并建议,什么应该是正确的代码和idref值应该与图id相同。我正在尝试使用分析字符串,但做不到。
输入
<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>发布于 2018-04-25 17:50:03
先考虑用钥匙查数字..。
<xsl:key name="figures" match="figure" use="lower-case(label)" />(我在这里使用小写,因为文本中有“图02”,而标签中有“图02”)。
您的主要问题是,在xsl:matching-substring中,您不再处于要匹配的原始节点的上下文中,因此您可能会收到一个类似于“上下文项不是节点”的错误。
要解决这个问题,请定义一个变量以允许您引用原始文档.
<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>发布于 2018-04-26 06:29:15
我用的是另一种方式,而不是钥匙,它也很好用。下面是做了一些更改的代码。
<?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>https://stackoverflow.com/questions/50027988
复制相似问题