изменить пространство имен элемента с помощью xslt - PullRequest
5 голосов
/ 05 ноября 2010

Я бы хотел сделать это

<hello>
  <one>
    <paragraph>p1</paragraph>
  </one>
</hello> 

в это

<x:hello y:an_attribute="a value for an_attribute" xmlns:x="some_new_namespace" xmlns:y="other_ns">
  <one>
    <paragraph>p1</paragraph>
  </one>
</x:hello> 

это таблица стилей, которую я придумал:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:param name="element_localname" select="'hello'"/>


    <xsl:template match="node()">
        <xsl:choose>
            <xsl:when test="local-name() = $element_localname">
                <xsl:element name="{$element_localname}" namespace="some_new_namespace">
                    <xsl:attribute name="an_attribute" namespace="other_ns">a value for an_attribute</xsl:attribute>
                    <xsl:apply-templates select="node()"/>
                </xsl:element>
            </xsl:when>

            <!-- copy the rest as is -->
            <xsl:otherwise> 
                <xsl:copy>
                    <xsl:apply-templates select="node()" />
                </xsl:copy>
            </xsl:otherwise>

        </xsl:choose>
    </xsl:template>

</xsl:stylesheet> 

но по какой-то странной причине атрибут, который я добавляю к элементу, имеет то же пространство имен, что и сам корневой элемент? почему?

<ns0:hello xmlns:ns0="other_ns" ns0:an_attribute="a value for an_attribute">
  <one>
    <paragraph>p1</paragraph>
  </one>
</ns0:hello>

Спасибо за чтение.

Ответы [ 2 ]

4 голосов
/ 05 ноября 2010

Это гораздо проще, чем может показаться :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:x="some_new_namespace" xmlns:y="other_ns"
 exclude-result-prefixes="x y">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="/*">
  <x:hello y:an_attribute="a value for an_attribute">
   <xsl:apply-templates/>
  </x:hello>
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к предоставленному документу XML :

<hello>
    <one>
        <paragraph>p1</paragraph>
    </one>
</hello>

желаемый, правильный результат получается:

<x:hello xmlns:x="some_new_namespace" xmlns:y="other_ns" y:an_attribute="a value for an_attribute">
    <one>
        <paragraph>p1</paragraph>
    </one>
</x:hello>
0 голосов
/ 05 ноября 2010

Эта таблица стилей:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:x="some_new_namespace"
    xmlns:y="other_ns">
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="element_localname" select="'hello'"/>
    <xsl:template match="node()|@*" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:choose>
            <xsl:when test="local-name() = $element_localname">
                <xsl:element name="x:{$element_localname}">
                    <xsl:attribute name="y:an_attribute">
                        <xsl:text>a value for an_attribute</xsl:text>
                    </xsl:attribute>
                    <xsl:apply-templates select="node()|@*"/>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="identity" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Вывод:

<x:hello y:an_attribute="a value for an_attribute"
         xmlns:y="other_ns" xmlns:x="some_new_namespace">
    <one>
        <paragraph>p1</paragraph>
    </one>
</x:hello>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...