Ответ 1
Ваш XSLT также удаляет атрибуты, потому что у вас нет шаблона, который бы их копировал. <xsl:template match="*">
соответствует только элементам, а не атрибутам (или тексту, комментариям или инструкциям по обработке).
Ниже приведена таблица стилей, которая удаляет все определения пространства имен из обработанного документа, но копирует все остальные узлы и значения: элементы, атрибуты, комментарии, текст и инструкции по обработке. Пожалуйста, обратите внимание на 2 вещи
- Копирование атрибутов как таковых недостаточно для удаления всех пространств имен. Также атрибут может принадлежать пространству имен, даже если содержащийся элемент не принадлежит пространству имен. Поэтому также необходимо создавать атрибуты, подобные элементам. Создание атрибутов выполняется с помощью элемента
<xsl:attribute>
. - Действительный документ XML не может содержать элемент с двумя или более атрибутами с таким же расширенным именем, но элементы могут содержать несколько атрибутов с одним и тем же локальным именем , если атрибуты имеют разные пространства имен. Это означает, что удаление префикс пространства имен из имени атрибута вызовет dataloss, если есть элемент, который имеет два атрибута с одним и тем же локальным именем. Другой из этих атрибутов будет удален (или перезаписан).
... и код:
<?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
, чтобы предотвратить соответствие элементов этому шаблону.