Я хочу сгенерировать гиперссылку для всех сносок фигуры в тексте, а идентификатор должен совпадать с идентификатором фигуры. - PullRequest
0 голосов
/ 25 апреля 2018

Пожалуйста, проверьте и предложите, какой код должен быть правильным, а значение idref должно совпадать с идентификатором фигуры.Я пытаюсь выполнить анализ строки, но не могу сделать.

Пожалуйста, проверьте и предложите, какой код должен быть правильным, а значение idref должно совпадать с идентификатором фигуры.Я пытаюсь выполнить анализ строки, но не могу сделать.

ввод

<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 голосов
/ 26 апреля 2018

Я использовал другой способ вместо ключа, он тоже работает хорошо.Ниже приведен код некоторых изменений.

<?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>
0 голосов
/ 25 апреля 2018

Сначала рассмотрите возможность использования ключа для поиска цифр ...

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...