我想为文本中的所有图形标注生成超链接,id应该与图标ID相同

时间:2018-04-25 17:19:17

标签: xslt

请检查并建议, 什么应该是正确的代码和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>

2 个答案:

答案 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>