Сериализация 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">
<cichlid xmlns:ci="http://www.cichlids.com" id="1">
<name>Zeus</name>
<color>gold</color>
<teeth>molariform</teeth>
<breeding-type>lekking</breeding-type>
</cichlid>
</ci:cichlids>
Процесс сериализации включал объявление пространства имен, которое находится в области действия cichlid
элемент, хотя он не используется на этом элементе. Я хотел бы удалить это объявление и сделать вывод похожим
Ожидаемый результат
<?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>
Я знаю, как изменить 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">
<cichlid id="1">
<name>Zeus</name>
<color>gold</color>
<teeth>molariform</teeth>
<breeding-type>lekking</breeding-type>
</cichlid>
</ci:cichlids>