Namespace ermitteln
theo
- xsl
0 Thomas J.S.0 theo0 Thomas J.S.0 theo
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" mit (<xsl:value-of select="name(document('schemafile.xsd')/*[local-name() = 'schema']/namespace::*)"/> nur eben nicht auf das richtige Attribute. Also vereinfacht möchte ich als Ergebnis haben:
something
wenn das schema entsprechend aufweist:
xmlns:something="http://www.somenamespace.com" targetNamespace="http://www.somenamespace.com"
Ware dankbar fuer einen Tipp,
Gruß
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
Hallo Thomas,
vielen Dank für die ausführliche Antwort.
<xsl:for-each select="document('schema.xsd')/*/namespace::*">
<xsl:value-of select="."/> -
<xsl:value-of select="name(.)"/>
</xsl:for-each>
Das hatte ich auch schon gemacht und dachte deshalb, dass ich richitg "ziele", da mir ja dann die URI als auch die Kurzfrom ausgegeben wird.
<xsl:variable name="NS" select="document('schema.xsd')/*[1]/@targetNamespace"/>
<xsl:value-of select="name(//*[namespace-uri() = $NS])"/>
So wäre es fein (ich parse mit xsl eine xml der verschieden xsd file zugeordnet sind) Also mein $NS hat den Inhalt der namespace-URI (geteste mit einer probeausgabe von $NS mit xsl:value-of). Die Anweisung danach <xsl:value-of select="name(//*[namespace-uri() = $NS])"/> bringt dann aber nur Erfolg, wenn in meiner XML auch Element mit dem Namespace vorhanden sind. Also wenn keine Elemente des Namespace vorhanden sind, dann gibt mir auch substring-before(name(//*[namespace-uri() = $NS]),':') nicht den prefix aus.
Gruß
Theo
Hallo,
<xsl:variable name="NS" select="document('schema.xsd')/*[1]/@targetNamespace"/>
<xsl:value-of select="name(//*[namespace-uri() = $NS])"/>So wäre es fein (ich parse mit xsl eine xml der verschieden xsd file zugeordnet sind) Also mein $NS hat den Inhalt der namespace-URI (geteste mit einer probeausgabe von $NS mit xsl:value-of). Die Anweisung danach <xsl:value-of select="name(//*[namespace-uri() = $NS])"/> bringt dann aber nur Erfolg, wenn in meiner XML auch Element mit dem Namespace vorhanden sind. Also wenn keine Elemente des Namespace vorhanden sind, dann gibt mir auch substring-before(name(//*[namespace-uri() = $NS]),':') nicht den prefix aus.
Jein, wenn im Schema nur xmlns="" und nicht xmlns:foo="" mit targetNamespace benutzt wurde, wird substring-before(...) wirklich nichts bringen, weil dann ist beim Element: name() = local-name().
Aber sonst hast du recht, wenn kein Element aus dem Namenstaum verwendet wird, gibts auch nichts anzuzeigen.
Aber ich weiss nicht, was du wirklich erreichen möchtest, vielleicht gibt nohc andere Wege dafür.
Grüße
Thomas
Hallo Thomas,
nun ja, muss ich vielleicht etwas weiter ausholen. Die xml datei enthält in nodes verweise auf zu importierende xml schema (zum validieren dieser xml). Frag micht nicht warum, die es so machen, aber es ist so und ich kann daran auch nichts ändern. Nun wollte ich gerne eine Aufstellung machen, welches XML schema welchen namensraum definiert. also Beispiel:
<root xmlns:eins="http://www.erstes.com" xmlns:neu="http://www.zweites.com"
xmlns:blau="http://www.drittes.com" xmlns="www.leer.com">
<schemalocation location="erstes.xsd"/>
<schemalocation location="zweites.xsd"/>
<schemalocation location="drittes.xsd"/>
.
.
.
</root>
So, und nun wollte ich eigentlich einfach eine Auflistung, welches Schema welchen Namespace definiert und welcher prefix dem Namespace zugeordnet ist.
Da ist mir halt keine bessere Lösung eingefallen.
Hallo,
nun ja, muss ich vielleicht etwas weiter ausholen. Die xml datei enthält in nodes verweise auf zu importierende xml schema (zum validieren dieser xml). Frag micht nicht warum, die es so machen, aber es ist so und ich kann daran auch nichts ändern.
Nun ja, ich weiss auch nicht was die damit bezwecken (außer dass eine ihre anwendungen so programmiert ist, dass Schema auf diese Weise aufgerufen werden, denn eigentlich müsste es ja so angegeben werden:
xsi:schemaLocation="http://example.com/foo foo.xsd http://example.com/bar bar.xsd"
Nun wollte ich gerne eine Aufstellung machen, welches XML schema welchen namensraum definiert. also Beispiel:
<root xmlns:eins="http://www.erstes.com" xmlns:neu="http://www.zweites.com"
xmlns:blau="http://www.drittes.com" xmlns="www.leer.com">
<schemalocation location="erstes.xsd"/>
<schemalocation location="zweites.xsd"/>
<schemalocation location="drittes.xsd"/>
.
.
.
</root>So, und nun wollte ich eigentlich einfach eine Auflistung, welches Schema welchen Namespace definiert und welcher prefix dem Namespace zugeordnet ist.
Na ja, _das_ kannst du ja:
<xsl:for-each select="document(schemalocation/@location)/*/namespace::*">
<xsl:value-of select="name(.)"/> - <xsl:value-of select="."/>
</xsl:for-each>
Grüße
Thomas