XML: Die Sache mit den Namespaces / XML: Automatischer Namespace-Report

XML: Automatischer Namespace-Report

XML: Automatischer Namespace-Report

➪ In vielen XML-Dokumenten werden mehrere Namespaces verwendet, oft wiederholt mit verschiedenem Namespace-Präfix. Mitunter werden für denselben Namespace-Präfix lokal unterschiedliche Namespaces verwendet. Das erhöht die Anforderungen an die Folgeprogrammierung.

Wenn Sie unterstellen, dass

erscheint die Problematik noch überschaubar. Es kann jedoch vorkommen, dass

Um zu sehen, welche Namespaces in einem XML-Dokument überhaupt benötigt werden und welche Präfixe diese Namespaces verwenden, können Sie mit folgendem XSL-Stylesheet arbeiten:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 extension-element-prefixes="xs ">
 <xsl:output method="xml" indent="yes" />
 <xsl:template match="/">
 <ListeNamespaces>
 <xsl:for-each-group 
  select="//*/descendant-or-self::*[namespace-uri() != ''], 
          //@*[namespace-uri() != '']"
  group-by="namespace-uri()">  
  <ns 
   nr="{position()}" 
   namespace="{current-grouping-key()}">
   <xsl:for-each-group 
      select="current-group()" 
      group-by="substring-before(name(), ':')">
    <prefix localname="{local-name()}" name="{name()}">
    <xsl:value-of select="current-grouping-key()"/>
    </prefix>
   </xsl:for-each-group>
   </ns>   
 </xsl:for-each-group>
 </ListeNamespaces>
 </xsl:template>
</xsl:stylesheet>

Je nach XML-Input könnte das Ergebnis folgendermaßen aussehen:


<ListeNamespaces>
   <ns nr="1" namespace="www.wilfried-grupe.de/Orte/2018">
      <prefix localname="Orte" name="ns1:Orte">ns1</prefix>
   </ns>
   <ns nr="2" namespace="www.wilfried-grupe.de/Ort">
      <prefix localname="Ort" name="ns2:Ort">ns2</prefix>
   </ns>
   <ns nr="3" namespace="www.wilfried-grupe.de/Mensch">
      <prefix localname="Mensch" name="ns3:Mensch">ns3</prefix>
   </ns>
   <ns nr="4" namespace="www.wilfried-grupe.de/Kauf">
      <prefix localname="Kauf" name="ns4:Kauf">ns4</prefix>
      <prefix localname="Kauf" name="ns5:Kauf">ns5</prefix>
   </ns>
   <ns nr="5" namespace="www.wilfried-grupe.de/Kauf2018">
      <prefix localname="Kauf" name="ns4:Kauf">ns4</prefix>
   </ns>
   <ns nr="6" namespace="UndNochnNamespace">
      <prefix localname="dieserwert" name="ns5:dieserwert">ns5</prefix>
   </ns>
</ListeNamespaces>

Sie sehen, dass der Namespace bei nr="4" zwei Präfixe hat, also unter verschiedenen Präfixen mehrfach auftaucht. Betrachten Sie noch nr="5" und nr="6", so stellen Sie fest, dass denselben Präfixes an anderer Stelle noch andere Namespaces zugewiesen wurden. Möglich ist das bei lokal unterschiedlicher Zuweisung von Präfixes und Namespaces.

Dieses Ergebnis ist Anlass für eine Gegenprobe: Welche Präfixe gibt es, und welche Namespaces wurden ihnen zugewiesen?


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 extension-element-prefixes="xs ">
 <xsl:output method="xml" indent="yes" />
 <xsl:template match="/">
 <ListePrefixe>
 <xsl:for-each-group 
  select="//*/descendant-or-self::*[namespace-uri() != ''], 
          //@*[namespace-uri() != '']"
  group-by="substring-before(name(), ':')">  
  <prefix name="{current-grouping-key()}"
   nr="{position()}" >
   <xsl:for-each-group 
     select="current-group()" 
     group-by="namespace-uri()">
    <namespace 
      localname="{local-name()}" 
      name="{name()}">
    <xsl:value-of select="current-grouping-key()"/>
    </namespace>
   </xsl:for-each-group>
  </prefix>   
 </xsl:for-each-group>
 </ListePrefixe>
 </xsl:template>
</xsl:stylesheet>

Und tatsächlich stellt sich heraus, dass die Namespace-Prefixe ns4 und ns5 jeweils doppelt belegt sind. Siehe auch .


<ListePrefixe>
   <prefix name="ns1" nr="1">
      <namespace 
       localname="Orte" 
       name="ns1:Orte">www.wilfried-grupe.de/Orte/2018</namespace>
   </prefix>
   <prefix name="ns2" nr="2">
      <namespace 
       localname="Ort" 
       name="ns2:Ort">www.wilfried-grupe.de/Ort</namespace>
   </prefix>
   <prefix name="ns3" nr="3">
      <namespace 
       localname="Mensch" 
       name="ns3:Mensch">www.wilfried-grupe.de/Mensch</namespace>
   </prefix>
   <prefix name="ns4" nr="4">
      <namespace 
       localname="Kauf" 
       name="ns4:Kauf">www.wilfried-grupe.de/Kauf</namespace>
      <namespace 
       localname="Kauf" 
       name="ns4:Kauf">www.wilfried-grupe.de/Kauf2018</namespace>
   </prefix>
   <prefix name="ns5" nr="5">
      <namespace 
       localname="Kauf" 
       name="ns5:Kauf">www.wilfried-grupe.de/Kauf</namespace>
      <namespace 
       localname="dieserwert" 
       name="ns5:dieserwert">UndNochnNamespace</namespace>
   </prefix>
</ListePrefixe>

Diese (meist lokalen) Neudeklarationen von Namespaces und Präfixes machen die Programmierung nicht unbedingt einfacher. Sie zeigen aber, dass eine Implementierung auf der Basis von local-name(), nicht einmal auf der Basis von name() ausreichend ist, um Namespace-orientierte Ergebnisse zu erzielen.

wg / 12. April 2018



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf.






Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/namespaces4.html