Thomas J.S.: Namespace ermitteln

Beitrag lesen

Hallo,

ich weiss nicht, ob das hier zu banal ist, aber ich bekomme es einfach nicht hin. Ich versuche den targetNamespace prefix eines XML Schema zu ermittel. Also ich moechte feststellen lassen, welchen Namespace das schema definiert. Ich dachte mir das geht so:

<xsl:value-of select="name(document('schemafile.xsd')/*[local-name() = 'schema']/namespace::*[namespace-uri() = @targetNamespace])"/>

aber das scheint ja wohl nicht zu funktionieren. Obwohl ich denke, dass ich erst einmal richtig "ziele"

Eigentlich zielst du nicht richtig.
Denn das Schem kann auch einfach einen Default-Namenrsaum (also ohne NS-Prefix) definieren:
xmlns="http://www.example.com" targetNamespace="http://www.example.com"

Aber auch das hilft dir nicht, du wirst nicht herausfinden was du möchtest (nicht wenn du das Schema untersucht und nicht ein XML, das ddas Schema benutzt)

Du kannst es ausprobieren. Folgendes zeigt dir alle Namensräme an, die im Schema verwendet werden:

<xsl:for-each select="document('schema.xsd')/*/namespace::*">
 <xsl:value-of select="."/> -
</xsl:for-each>

Folgendes gibt erstens die Attribute im <schema>-Element aus (wobei du feststell wirst, dass alle @xmlns-Attribute in der Ausgabe fehlen werden) und zweitens den Namen des ersten Elementes, das im im '@targetNamespace' definierten Namensraum ist (es wird nichts ausgegeben).

<xsl:for-each select="document('schema.xsd')/*[1]">
 <xsl:variable name="NS" select="@targetNamespace" />

Elem.Name: <xsl:value-of select="name()"/>
 <xsl:for-each select="@*">
  Att.Name: <xsl:value-of select="name()"/>
  Att.Val: <xsl:value-of select="."/>
 </xsl:for-each>

1. Elem. in @targetNamespace:  <xsl:value-of select="name(.//*[namespace-uri() = $NS])"/>
</xsl:for-each>

Eine unzuverlässige Möglichkeit wäre um den NS-Prefix herauszufinden, wenn du versuchen würdest die "type"-Attribute (z.B. in einem Elemente-Definition: <xs:element name="foo" type="fooType" />) zu untersuchen.
Wenn im <schema>-Element so etwas wie
   xmlns:bar="http://www.example.com"
   targetNamespace="http://www.example.com"
definiert wurde, würde die Element-Definition so lauten:
<xs:element name="foo" type="bar:fooType" />

Da könntest du den Prefix mit substring-before(@type, ':') bekommen, ABER wie gesagt, das ist sehr unzuverlässig, denn du hast keine Möglichgkeit zu einem Vergleich und wenn das Schema andere Schemas (mit Namensraumangabe) importiert, kommt die ganze Sache durcheinander.

Besser wäre du würdest es über ein XML, das das Schema verwendet, zu versuchen:

<xsl:variable name="NS" select="document('schema.xsd')/*[1]/@targetNamespace"/>
<xsl:value-of select="name(//*[namespace-uri() = $NS])"/>

von da kannst du den Prefix, falls vorhanden, herausfinden.

Grüße
Thomas