2010-11-05 21 views
5

Chciałbym, aby tenzmianę nazw elementu z XSLT

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

w tym

<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> 

jest to arkusz stylów wymyśliłem:

<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> 

ale z jakiegoś dziwnego powodu atrybut dodawany do elementu ma taką samą przestrzeń nazw jak sam element główny? czemu?

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

Dziękuję za przeczytanie.

+0

Running źródło pośrednictwem transformacji xsltproc daje mi ' "dla elementu' hello', który wydaje się być tym, czego potrzebujesz. Zastanawiam się, czy to jest XSL 1.0 versus XSL 2.0? –

+0

Dzięki za próby. Używam eclipse wtp build w procesorze xslt. Nie mam pojęcia, jakiej implementacji używa. – Luca

+0

Dobre pytanie, +1. Zobacz moją odpowiedź na znacznie prostsze i krótsze rozwiązanie niż obecnie akceptowane. :) –

Odpowiedz

0

arkusz stylów:

<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> 

wyjściowa:

<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> 
+0

Dziękuję, to działa. Rozwiązałeś mój problem :) Czy masz pomysł, dlaczego mój przykład nie? – Luca

+0

@ Luca: Jesteś mile widziany. To jest kod wyjściowy: ' p1' Tak , masz element docelowy defalut root z atrybutem w przestrzeni nazw niezerowej (przedrostek jest automatycznie dodawany przez Namespaces Fixup) i zresetowaną domyślną deklarację przestrzeni nazw 'xmlns =" ​​"(W XML 1.1 również prefiksowana deklaracja przestrzeni nazw może być zresetowana.) . Dolna linia: jeśli chcesz powiązać identyfikator URI specyficznego prefiksu-nazwy, zadeklaruj go w arkuszu stylów. –

4

To znacznie prostsze niż mogłoby się wydawać:

<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> 

kiedy ta transformacja jest stosowane do dostarczonego Dokument XML:

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

poszukiwany, poprawny wynik jest produkowany:

<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> 
Powiązane problemy