XProc и CDATA

У меня есть XSLT, который создает CDATA внутри узла.

XML:

<test><inner>stuff</inner></test>

XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="test">
        <wrapper>
                <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                <xsl:copy-of select="*"/>
                <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
        </wrapper>
    </xsl:template>
</xsl:stylesheet>

Это преобразование, выполненное через Saxon, возвращает:

<wrapper><![CDATA[<inner>stuff</inner>]]></wrapper>

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

Теперь я пытаюсь включить это преобразование как часть более крупного конвейера XProc:

<p:pipeline xmlns:p="http://www.w3.org/ns/xproc" version="1.0" >
<p:xslt>
    <p:input port="stylesheet">
        <p:document href="test.xsl" />
    </p:input>
</p:xslt>

Который возвращает (используя последнюю версию Calabash):

<wrapper>&lt;![CDATA[<inner>stuff</inner>]]&gt;</wrapper>

Кажется, что XProc не соблюдает атрибут disable-output-escaping.

Я попробовал несколько функций XProc, включая p: unescape-markup и различные комбинации p: string-replace, но я не смог найти решение, которое не оказало бы негативного влияния на остальную часть моего вывода.

Есть идеи, что я мог бы попробовать дальше?

1 ответ

Решение

XSLT-процессор не требуется для поддержки doe:

Процессор XSLT сможет отключить экранирование только в том случае, если он контролирует, как выводится дерево результатов. Это не всегда так. Например, дерево результатов может использоваться как исходное дерево для другого преобразования XSLT вместо вывода.

Это особенно верно при конвейерной обработке: XSLT может не управлять сериализацией выходного дерева, а только передавать его на следующий шаг в конвейере как DOM или как события SAX. Но даже если бы мог,

XSLT-процессор не обязан поддерживать отключение экранирования выходных данных. Если xsl:value-of или xsl:text указывает, что выходное экранирование должно быть отключено, а процессор XSLT не поддерживает это, процессор XSLT может сигнализировать об ошибке; если он не сигнализирует об ошибке, он должен восстановиться, не отключая экранирование выхода.

Таким образом, вы действительно не можете полагаться на Доу, особенно в трубопроводе.

Но это то, что ожидается от API, с которым я работаю, поэтому у меня нет выбора, кроме как следовать этой схеме.

Я могу сочувствовать ситуации, использовав в прошлом неисправные инструменты, потому что они были лучшими из доступных. Однако наличие (и границы) раздела CDATA явно отсутствует в информационном наборе XML. Таким образом, API, который зависит от разделов CDATA, является ошибочным с точки зрения его требований к вводу XML. Если это действительно зависит от разделов CDATA, было бы неплохо подать отчет об ошибке об этом.

С другой стороны, возможно API, с которым вы работаете, на самом деле не требует разделов CDATA; может быть, это просто требует, чтобы вы подали ему XML, который каким-то образом избежал? Если это так, есть другие способы сделать это, не требуя специальной сериализации, которая находится за пределами XML Infoset. Если вы можете показать нам документацию об API, мы могли бы помочь определить, что на самом деле требуется.

Другие вопросы по тегам