Odstranění jmenného prostoru

Odstranění namespace mění jména elementů a může sloučit různá data. Dělej ho jen tehdy, když cílový formát opravdu požaduje XML bez namespace.

Autor: Aktualizováno

Odstranění prefixu není odstranění namespace

P:kniha a kniha mohou mít stejné URI namespace. Pouhé přepsání prefixu nebo smazání xmlns regexem není spolehlivá transformace: může vytvořit nedeklarované prefixy nebo změnit význam atributových hodnot QName.

Odstranění prefixu není odstranění namespace
<a:id xmlns:a="urn:A">1</a:id>
<b:id xmlns:b="urn:B">2</b:id>
<!-- oba se po odstranění namespace stanou id -->

XSLT 1.0 pro elementy a atributy

Tato transformace vytvoří nová jména podle local-name. Před spuštěním musíš vyloučit kolize atributů ze dvou prostorů a hodnoty typu QName, jejichž význam by se bez vazby prefixů ztratil. Není určena pro podepsané dokumenty.

XSLT 1.0 pro elementy a atributy
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" omit-xml-declaration="yes"/>
 <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="text()|comment()|processing-instruction()"><xsl:copy/></xsl:template>
</xsl:stylesheet>

Bezpečnější alternativa pro dotaz

Pokud jen XPath nenachází uzly, namespace neodstraňuj. Naváž prefix v dotazu na skutečné URI. Použití local-name v dotazu může být vhodné pro diagnostiku, ale bez namespace-uri může vybrat jiný prvek téhož místního jména.

Kontrola výsledku

Po převodu ověř cílové schéma a počet záznamů, příznaky xml:lang/xml:space i kolize jmen. Výše uvedená transformace odstraní namespace i z atributů xml:* a tím jejich zvláštní význam; pro zachování je potřeba zvláštní pravidlo.

Vstup, výstup a spuštění transformace

vstup.xml — známý jednoduchý model bez QName hodnot
<k:katalog xmlns:k="urn:knihy"><k:kniha id="k1"><k:nazev>XML</k:nazev></k:kniha></k:katalog>
výstup.xml — očekávaný model bez namespace
<katalog><kniha id="k1"><nazev>XML</nazev></kniha></katalog>
Úvodní stylesheet ulož jako bez-namespace.xsl
xsltproc bez-namespace.xsl vstup.xml > vystup.xml
xmllint --noout vystup.xml

První příkaz vytvoří nové neprefixované elementy, druhý ověří jejich XML syntax. Následně validuj výsledek proti schématu určenému pro dokument bez namespace. Původní schéma pro urn:knihy po změně jmen přirozeně nemusí projít. Výstup může být správně zapsané XML, a přesto nesplňovat původní XSD.

Vyzkoušej <r xmlns:a="urn:A" xmlns:b="urn:B" a:id="1" b:id="2"/>. Po odstranění prostoru by oba atributy měly jméno id, což model nesmí bez rozhodnutí sloučit. Před transformací takovou kolizi odmítni. Při QName hodnotě a:Typ by ztráta deklarace namespace změnila či zničila její význam, přestože string v atributu zůstane stejný.

Pokud potřebuješ zachovat xml:lang a xml:space, doplň specializované kopírovací pravidlo pro atributy v XML namespace. Nejde o univerzální „beznamespace“ transformaci. Pro pouhý XPath dotaz je vhodnější správná vazba prefixu.