XSLT удаляет нс из XML

Aug 29 2020

Проблемы с созданием ожидаемого XML с использованием XSLT, в котором я пытаюсь добиться управления версиями XML и хочу удалить тег id из XML. XSLT удаляет тег, но он добавляется xmlns=""как атрибут каждого тега в выводе.

XML выглядит так

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Customer xmlns="urn:com:xmlschema:service:v1.1:Address.xsd">
    <ID>123</ID>
    <Status>PRESENT</Status>
    <InternetAddress>00:00:00:00:00</InternetAddress>
    <PhysicalAddress>SOME ADDRESS</PhysicalAddress>
    <FamilyMember>8</FamilyMember>
</Customer>

XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="urn:com:xmlschema:service:v1.1:Address.xsd"
                exclude-result-prefixes="#all" >
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="*">
        <xsl:element name="{local-name(.)}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:attribute name="{local-name(.)}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    <xsl:template match="ns:Customer">
        <Customer xmlns="urn:com:xmlschema:service:v2.1:Address.xsd">
            <xsl:apply-templates select="@*|node()"/>
        </Customer>
    </xsl:template>
    <xsl:template match="ns:ID"/>
</xsl:stylesheet>

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

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Customer xmlns="urn:com:xmlschema:service:v2.1:Address.xsd">
    <Status>PRESENT</Status>
    <InternetAddress>00:00:00:00:00</InternetAddress>
    <PhysicalAddress>SOME ADDRESS</PhysicalAddress>
    <FamilyMember>8</FamilyMember>
</Customer>

XSLT создан

<?xml version="1.0" encoding="UTF-8"?>
<Customer xmlns="urn:com:xmlschema:service:v2.1:Address.xsd">
   <Status xmlns="">PRESENT</Status>
   <InternetAddress xmlns="">00:00:00:00:00</InternetAddress>
   <PhysicalAddress xmlns="">SOME ADDRESS</PhysicalAddress>
   <FamilyMember xmlns="">8</FamilyMember>
</Customer>

xmlns=""Я хочу удалить. Пожалуйста, подскажите, где я совершаю ошибку.

Ответы

2 zx485 Aug 29 2020 at 08:38

Вы пытались удалить пространства имен дочерних элементов вашего корневого элемента. Это сработало, отсюда и расширение xmlns=''. Но он xmlns=...устанавливает пространство имен по умолчанию для всех его дочерних элементов, которое вы пытались отменить в своих первых двух шаблонах.

Чтобы получить желаемый результат, вы можете избавиться от этих шаблонов и просто использовать шаблон удаления с шаблоном, который изменяет пространство имен всех элементов на новое:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="urn:com:xmlschema:service:v1.1:Address.xsd" exclude-result-prefixes="#all" >
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="ns:*">
        <xsl:element name="{local-name()}" namespace="urn:com:xmlschema:service:v2.1:Address.xsd">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
    
    <xsl:template match="ns:ID"/>
</xsl:stylesheet>

Его результат желаемый (предположительно):

<?xml version="1.0" encoding="UTF-8"?>
<Customer xmlns="urn:com:xmlschema:service:v2.1:Address.xsd">
   <Status>PRESENT</Status>
   <InternetAddress>00:00:00:00:00</InternetAddress>
   <PhysicalAddress>SOME ADDRESS</PhysicalAddress>
   <FamilyMember>8</FamilyMember>
</Customer>

Это работает даже в XSLT-1.0.