Как сохранить escape-символы в исходном дереве в дереве результатов? - PullRequest
0 голосов
/ 07 января 2020

Я пишу XSL, который предназначен для преобразования одного XML файла в другой XML файл. Исходное дерево содержит & в текстовом узле. Я хочу, чтобы это сохранилось в дереве результатов, но после вывода оно становится голым &.

У меня есть <xsl:output> со следующими атрибутами: method = "xml", version = "1.0", encoding = "UTF-8", standalone = "yes".

Я пытался использовать карту символов для & (не могу сделать это, потому что naked & недопустимо XML, а XSL равно XML), для &amp; (ничего не соответствует ) и &amp;amp; (это более одного символа, поэтому не может вписаться в @character из <xsl:output-character>

Если я изменю исходные XML экземпляров &amp; на &amp;amp;, то вывод XSL имеет желаемое значение &amp;. Однако я не хочу вводить еще один шаг в этом процессе.

Я также попытался сделать вывод html. Это не помогло.

Я пытался использовать cdata-section-elements для результирующих узлов, которые могут содержать &amp;, но я получаю ошибку от парсера: значение {cdata-section-elements} должно быть списком QNames в ' {uri} локальная нотация

<?xml version="1.0" encoding="UTF-8"?>
<PRESENTATION>
    <CONTROL_ID>3199846</CONTROL_ID>
    <PRESENTATION_ID>2726948</PRESENTATION_ID>
    <SESSION_TRACK>abc</SESSION_TRACK>
    <FINAL_ID>4</FINAL_ID>
    <TITLE>abc</TITLE>
    <STATUS>Sessioned</STATUS>
    <AUTHORS>
        <AUTHOR order="1" person_id="5811496" presenter="true">
            <FNAME>Newhart</FNAME>
            <MNAME/>
            <LNAME>Bob</LNAME>
            <EMAIL>newhart@bob.com</EMAIL>
            <DEGREE/>
            <AFFILIATIONS>
                <AFFL author_order="1" number="1">
                    <DEPT>Psychiatry &amp; Other things</DEPT>
                    <INST>Zippers</INST>
                    <CITY>Frankfurt</CITY>
                    <STATE>Hesse</STATE>
                    <COUNTRY>Germany</COUNTRY>
                </AFFL>
            </AFFILIATIONS>
        </AUTHOR>
    </AUTHORS>
    <BODY>
        <SECTION part_of_body="0">
            <SECTION_NAME bold="true"
                italic="false"
                underline="false"
                name_appears="true">Abstract</SECTION_NAME>
            <TEXT>This will not be relevant.</TEXT>
        </SECTION>
    </BODY>
</PRESENTATION>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">

    <xsl:output method="xml"
                version="1.0"
                encoding="UTF-8"
                standalone="yes"/>


    <xsl:template match="/">
                    <xsl:choose>
                        <xsl:when test="/PRESENTATION/AUTHORS/AUTHOR">
                            <contrib-group>
                                <!-- Handle 1 or more authors -->
                                <xsl:for-each select="/PRESENTATION/AUTHORS/AUTHOR">
                                    <xsl:variable name="currentAuthor" select="current()"/>
                                    <contrib>
                                        <name name-style="western">
                                            <surname>
                                                <xsl:value-of select="$currentAuthor/LNAME"/>
                                            </surname>
                                            <given-names>
                                                <xsl:value-of select="$currentAuthor/FNAME"/>
                                                <xsl:if test="matches($currentAuthor/MNAME, '.+')">
                                                    <xsl:value-of select="concat(' ', ./MNAME)"/>
                                                </xsl:if>
                                            </given-names>
                                        </name>

                                        <xsl:for-each select="/$currentAuthor/AFFILIATIONS/AFFL">
                                            <xsl:variable name="currentAff" select="current()"/>
                                            <xsl:if test="position() = 1">
                                                <aff>
                                                    <xsl:if test="$currentAff/DEPT">
                                                        <xsl:apply-templates select="$currentAff/DEPT"/>
                                                    </xsl:if>

                                                    <xsl:if test="$currentAff/INST">
                                                        <institution>
                                                            <xsl:apply-templates select="$currentAff/INST"/>
                                                        </institution>
                                                    </xsl:if>
                                                </aff>
                                            </xsl:if>
                                        </xsl:for-each>

                                    </contrib>
                                </xsl:for-each>
                            </contrib-group>
                        </xsl:when>    
                    </xsl:choose>
    </xsl:template>


    <xsl:template match="text()">
        <xsl:if test="position() > 1">
            <xsl:text> </xsl:text>
        </xsl:if>

        <xsl:value-of select="normalize-space(.)" disable-output-escaping="yes"/>

    </xsl:template>

    <xsl:template name="superscript-preserver" match="sup">
        <sup>
            <xsl:value-of select="normalize-space(.)"/>
        </sup>
    </xsl:template>

    <xsl:template name="subscript-preserver" match="sub">
        <sub>
            <xsl:value-of select="normalize-space(.)"/>
        </sub>
    </xsl:template>

    <xsl:template name="italic-space-normalizer" match="i">
        <xsl:value-of select="normalize-space(.)"/>
    </xsl:template>

    <xsl:template name="bold-space-normalizer" match="b">
        <xsl:value-of select="normalize-space(.)"/>
    </xsl:template>

    <xsl:template name="underline-space-normalizer" match="u">
        <xsl:value-of select="normalize-space(.)"/>
    </xsl:template>

    <xsl:template name="br-space-normalizer" match="br">
        <xsl:value-of select="normalize-space(.)"/>
        <xsl:text> </xsl:text>
    </xsl:template>

    <xsl:template name="square-bracket-extractor" match="/PRESENTATION/SESSION_TRACK">
        <!-- extract string between square brackets -->
        <xsl:analyze-string select="." regex="(.+)">
            <xsl:matching-substring>
                <!-- Take the result from the 1st regex match group and do a replacement. -->
                <xsl:sequence select="replace(regex-group(1), 'I&amp;EC', 'I+EC')"/>
            </xsl:matching-substring>
        </xsl:analyze-string>
    </xsl:template>

    <xsl:template name="final-id-format" match="/PRESENTATION/FINAL_ID">
        <xsl:value-of select="format-number(., '0000')"/>
    </xsl:template>

</xsl:stylesheet>

1 Ответ

0 голосов
/ 08 января 2020

Вы явно попросили процессор не выходить из амперсанда, используя disable-output-escaping = "yes". Если вы хотите, чтобы он сбежал, не отключайте его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...