Ваш XSLT также удаляет атрибуты, потому что у вас нет шаблона, который бы копировал их.<xsl:template match="*">
соответствует только элементам, а не атрибутам (или тексту, комментариям или инструкциям по обработке).
Ниже приведена таблица стилей, которая удаляет все определения пространства имен из обработанного документа, но копирует все другие узлы и значения: элементы, атрибуты,комментарии, текст и инструкции по обработке.Обратите внимание на 2 вещи
- Копирование атрибутов как таковых недостаточно для удаления всех пространств имен.Также атрибут может принадлежать пространству имен, даже если содержащий элемент не принадлежит пространству имен.Поэтому также необходимо создавать атрибуты, такие как элементы.Создание атрибутов выполняется с помощью элемента
<xsl:attribute>
. - Действительный документ XML не может содержать элемент, имеющий два или более атрибутов с одинаковым расширенным именем, но элементы могут содержать несколько атрибутов с одинаковым локальным именем , если атрибутыимеют разные пространства имен. Это означает, что удаление префикса пространства имен из имени атрибута приведет к потере данных, если есть элемент, имеющий по крайней мере два атрибута с одинаковым локальным именем.Другой один из этих атрибутов будет удален (или перезаписан).
... и код:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>
<!-- Stylesheet to remove all namespaces from a document -->
<!-- NOTE: this will lead to attribute name clash, if an element contains
two attributes with same local name but different namespace prefix -->
<!-- Nodes that cannot have a namespace are copied as such -->
<!-- template to copy elements -->
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<!-- template to copy attributes -->
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!-- template to copy the rest of the nodes -->
<xsl:template match="comment() | text() | processing-instruction()">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
Вы также можете использовать <xsl:template match="node()">
вместо этого последнего шаблонано тогда вы должны использовать атрибут priority
, чтобы элементы не соответствовали этому шаблону.