Сериализация XPath 3.0 без пространств имен в области

Отвечая на этот вопрос, мне пришло в голову, что я знаю, как использовать XSLT 3.0 (XPath 3.0) serialize() функция, но я не знаю, как избежать сериализации пространств имен, которые находятся в области видимости. Вот минимальный пример:

Ввод XML

<?xml version="1.0" encoding="UTF-8" ?>
<ci:cichlids xmlns:ci="http://www.cichlids.com">
    <cichlid id="1">
        <name>Zeus</name>
        <color>gold</color>
        <teeth>molariform</teeth>
        <breeding-type>lekking</breeding-type>
    </cichlid>
</ci:cichlids>

Таблица стилей XSLT 3.0

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization"
    xmlns:ci="http://www.cichlids.com">

    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/ci:cichlids/cichlid">
        <xsl:variable name="serial-params">
            <output:serialization-parameters>
                <output:omit-xml-declaration value="yes"/>
            </output:serialization-parameters>
        </xsl:variable>
        <xsl:value-of select="serialize(., $serial-params/*)"/>
    </xsl:template>

</xsl:stylesheet>

Фактический вывод

<?xml version="1.0" encoding="UTF-8"?>
<ci:cichlids xmlns:ci="http://www.cichlids.com">
    &lt;cichlid xmlns:ci="http://www.cichlids.com" id="1"&gt;
        &lt;name&gt;Zeus&lt;/name&gt;
        &lt;color&gt;gold&lt;/color&gt;
        &lt;teeth&gt;molariform&lt;/teeth&gt;
        &lt;breeding-type&gt;lekking&lt;/breeding-type&gt;
    &lt;/cichlid&gt;
</ci:cichlids>

Процесс сериализации включал объявление пространства имен, которое находится в области действия cichlid элемент, хотя он не используется на этом элементе. Я хотел бы удалить это объявление и сделать вывод похожим

Ожидаемый результат

<?xml version="1.0" encoding="UTF-8"?>
<ci:cichlids xmlns:ci="http://www.cichlids.com">
    &lt;cichlid id="1"&gt;
        &lt;name&gt;Zeus&lt;/name&gt;
        &lt;color&gt;gold&lt;/color&gt;
        &lt;teeth&gt;molariform&lt;/teeth&gt;
        &lt;breeding-type&gt;lekking&lt;/breeding-type&gt;
    &lt;/cichlid&gt;
</ci:cichlids>

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

Что такое канонический способ сериализации элемента XML с использованием serialize() функция также без сериализации неиспользуемых объявлений пространства имен, которые находятся в области видимости?


Тестирование с Saxon-EE 9.6.0.7 изнутри Кислород.

2 ответа

Решение

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

Майкл Кей уже дал правильный ответ, и я его принял. Это просто, чтобы конкретизировать его комментарии. От

Запустите преобразование, чтобы удалить ненужные пространства имен, а затем сериализуйте результат.

он подразумевает применение преобразования, подобного следующему, перед вызовом serialize():

Таблица стилей XSLT

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization"
    xmlns:ci="http://www.cichlids.com">

    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:variable name="cichlid-without-namespace">
        <xsl:copy-of copy-namespaces="no" select="/ci:cichlids/cichlid"/>
    </xsl:variable>

    <xsl:template match="/ci:cichlids/cichlid">
        <xsl:variable name="serial-params">
            <output:serialization-parameters>
                <output:omit-xml-declaration value="yes"/>
            </output:serialization-parameters>
        </xsl:variable>
        <xsl:value-of select="serialize($cichlid-without-namespace, $serial-params/*)"/>
    </xsl:template>

</xsl:stylesheet>

Вывод XML

<?xml version="1.0" encoding="UTF-8"?>
<ci:cichlids xmlns:ci="http://www.cichlids.com">
    &lt;cichlid id="1"&gt;
        &lt;name&gt;Zeus&lt;/name&gt;
        &lt;color&gt;gold&lt;/color&gt;
        &lt;teeth&gt;molariform&lt;/teeth&gt;
        &lt;breeding-type&gt;lekking&lt;/breeding-type&gt;
    &lt;/cichlid&gt;
</ci:cichlids>
Другие вопросы по тегам