Я пишу XSL, который предназначен для преобразования одного XML файла в другой XML файл. Исходное дерево содержит &
в текстовом узле. Я хочу, чтобы это сохранилось в дереве результатов, но после вывода оно становится голым &.
У меня есть <xsl:output>
со следующими атрибутами: method = "xml", version = "1.0", encoding = "UTF-8", standalone = "yes".
Я пытался использовать карту символов для & (не могу сделать это, потому что naked & недопустимо XML, а XSL равно XML), для &
(ничего не соответствует ) и &amp;
(это более одного символа, поэтому не может вписаться в @character из <xsl:output-character>
Если я изменю исходные XML экземпляров &
на &amp;
, то вывод XSL имеет желаемое значение &
. Однако я не хочу вводить еще один шаг в этом процессе.
Я также попытался сделать вывод html. Это не помогло.
Я пытался использовать cdata-section-elements для результирующих узлов, которые могут содержать &
, но я получаю ошибку от парсера: значение {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 & 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&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>