Molko
asked on
XSLT - XPath to the XSI definition attribute
I have some xml that I wish to transform, the transformation is dependant upon the
xsi:schemaLocation="http://example/prodv1.xsd http://example/otherstuff.xsd"
or
xsi:schemaLocation="http://example/otherstuff.xsd http://example/prodv2.xsd"
If its prov1 i want to do something, if its prodv2 i do something else. I guess they can come in any order as well
I can write the xpath to pick out all attributes (@*), but I can figure out a way to return a boolean (xpath) that evaulates the existance of http://example/prodv1.xsd
xsi:schemaLocation="http://example/prodv1.xsd http://example/otherstuff.xsd"
or
xsi:schemaLocation="http://example/otherstuff.xsd http://example/prodv2.xsd"
If its prov1 i want to do something, if its prodv2 i do something else. I guess they can come in any order as well
I can write the xpath to pick out all attributes (@*), but I can figure out a way to return a boolean (xpath) that evaulates the existance of http://example/prodv1.xsd
<?xml version="1.0" encoding="UTF-8"?>
<order xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://example/prodv1.xsd
http://example/prodv2.xsd">
<items>
<product>
<number xsi:type="xs:short">557</number>
<name>Short-Sleeved Linen Blouse</name>
<size xsi:nil="true"/>
</product>
</items>
</order>
ASKER
Sorry, oops...a typo
I can write the xpath to pick out all attributes (@*), but I cant figure out a way to return a boolean (xpath) that evaulates the existance of http://example/prodv1.xsd
I can write the xpath to pick out all attributes (@*), but I cant figure out a way to return a boolean (xpath) that evaulates the existance of http://example/prodv1.xsd
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
inside the predicate the expression renders to a boolean expression which is false if the returned nodeset is empty
You might be up to a somewhat bigger challenge
seems to imply that you are uncertain about the meaning of schemaLocation
schemaLocation has two components
the part before the space is the targetNamespace of the schema referenced, it is a URI, a resource identifier, which often takes the form of a URL, but it isn't one
the second part (after the white space) is the physical location of the schema, it is a URL and it should point to the actual schema.
Order in an @xsi:schemaLocation is important
For schema that don't have a target namespace there is
@xsi:noNamespaceSchemaLoca tion
It could be that you also have to test for that
Now the use of schemaLocation implies that the schema you are referring to has a targetNamespace. In that case, chances are that the XML elements defined in that schema are in that namespace. So most often you will find that attribute with an xmlns="..."
In that case the templates will not work, because you can't address the order element in the null namespace if it is in the schema target namespace
So you might have to make the XSLT namespace independent, using local-name(), like this
In XSLT2 you can simply wildcard match="/*:order" but the above XSLT will work in both
You might be up to a somewhat bigger challenge
I guess they can come in any order as well
seems to imply that you are uncertain about the meaning of schemaLocation
schemaLocation has two components
the part before the space is the targetNamespace of the schema referenced, it is a URI, a resource identifier, which often takes the form of a URL, but it isn't one
the second part (after the white space) is the physical location of the schema, it is a URL and it should point to the actual schema.
Order in an @xsi:schemaLocation is important
For schema that don't have a target namespace there is
@xsi:noNamespaceSchemaLoca
It could be that you also have to test for that
Now the use of schemaLocation implies that the schema you are referring to has a targetNamespace. In that case, chances are that the XML elements defined in that schema are in that namespace. So most often you will find that attribute with an xmlns="..."
In that case the templates will not work, because you can't address the order element in the null namespace if it is in the schema target namespace
So you might have to make the XSLT namespace independent, using local-name(), like this
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xsi"
version="1.0">
<xsl:template match="/">
<xsl:apply-templates select="/*"/>
</xsl:template>
<xsl:template match="/*[local-name() = 'order'][contains(@xsi:schemaLocation, 'http://example/prodv1.xsd')]">
do one thing here
</xsl:template>
<xsl:template match="/*[local-name() = 'order'][not(contains(@xsi:schemaLocation, 'http://example/prodv1.xsd'))]">
do other thing here
</xsl:template>
</xsl:stylesheet>
In XSLT2 you can simply wildcard match="/*:order" but the above XSLT will work in both
ASKER
Thankyou.
welcome
/order[conatins(@xsi:schem