How to retrieve specific namespace in XML files using Xpath - xslt

I do have an XML file that starts as following:
<wfs:WFS_Capabilities xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" ...>
I do have the full xml file in an xsl:variable named="CAPAPILITIES" and the namespace identifier "ogc" in an xsl:variable named "prefix". I tried the following but it does not work:
<xsl:value-of select="$CAPABILITIES/namespace::*[name()='$prefix']" />

and the namespace identifier "ogc" in an xsl:variable named "prefix"
You need to remove the quotes around $prefix:
<xsl:value-of select="$CAPABILITIES/namespace::*[name()=$prefix]" />
in order to compare the namespace node's name() against the value of the prefix variable instead of against the literal string "dollar-prefix".

Related

Use XSLT to reveal Page XMLNS

I am creating a quick-ref stylesheet for my XML files, and part of that reference is seeing which xml namespace I am using in each file.
For example, the start tage of gen_info.xml is:
<GeneralInfo xmlpre="Gen" xmlns="http://www.mrinitialman.com/">
Displaying the attribute "xmlpre" is easy enough: <xsl:value-of select="#xmlpre" /> . But <xsl:value-of select="#xmlns" /> seems to do nothing. What am I missing?
What am I missing?
You are missing the fact that xmlns="http://www.mrinitialman.com/" is not an attribute but a namespace declaration. It puts the GeneralInfo element and its descendants in a default namespace whose URI is "http://www.mrinitialman.com/".
You can use the namespace-uri() function to retrieve the namespace URI of a node. If - as it seems* - you are in the context of the GeneralInfo element, then:
<xsl:value-of select="namespace-uri()"/>
will return:
http://www.mrinitialman.com/
Note that an element can be in a namespace inherited from an ancestor element or determined by a prefix attached to its name; IOW, the namespace-uri() function returns the namespace URI of the argument node, not of a namespace declaration.
--
(*) It's not clear from your question how you get into the context of the GeneralInfo element, since it is in a namespace.

Output multiple namespace definitions with XSLT 1.0

I need to generate the following output :
<x:Envelope xmlns:x='namespace1'>
<x:Root xmlns="namespace2">
<Header>
...
</Header>
</x:Root>
</x:Envelope>
I'm having trouble generating the default namespace for the x:Root element using xslt 1.0. I can get it to have no namespace ( but namespace2 will be specified on children of root - undesired behaviour ) or have it with a prefix :
<x:Root xmlns:x="namespace2">
but this fails schema validation. Any ideas ?
Edit : sorry for the ambiguous question and thanks for the answers. Root should be in namespace1 and Header should be in namespace2. However, the request is that namespace2 should not be declared in Header, but at Root level.
Regards,
It depends on how much of this is known statically. If you know everything statically, the literal result element
<x:Root xmlns="namespace2">..</x:Root>
will generate exactly what you want. In the more general case, you need to construct an element containing the required namespace node and then copy the namespace node:
<xsl:param name="ns">namespace2</xsl:param>
<xsl:variable name="temp">
<xsl:element name="dummy" namespace="{$ns}"/>
</xsl:variable>
...
<xsl:element name="Root">
<xsl:copy-of select="xx:node-set($temp)/namespace::*"/>
</xsl:element>
All so much easier in XSLT 2.0 with the xsl:namespace instruction.
You can't map two different namespaces to the same prefix "x". Instead, leave off the prefix for Root all together like this:
<Root xmlns="namespace2">
...
</Root>

XSLT: How get rid of default namespace's prefixes in XPath? (xmlns="...")

I have a template:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:jboss:domain:1.1"
xmlns:d="urn:jboss:domain:1.1"
>
...
<xsl:template match="//d:interfaces/d:interface[#name='management']/d:inet-address">
...
</xsl:template>
This works.
<xsl:template match="//interfaces/interface[#name='management']/inet-address">
...
</xsl:template>
Why this doesn't work despite I have a default namespace set?
<xsl:template match="//interfaces/interface[#name='management']/inet-address">
...
</xsl:template>
Why this doesn't work despite I have a default namespace set?
This is one of the most FAQ on any XSLT and/or XPath list.
XPath treats any unprefixed name as belonging to "no namespace" -- regardless of the fact that there may be a default namespace defined and in scope.
To quote the W3C XPath 1.0 specification:
"A QName in the node test is expanded into an expanded-name using the
namespace declarations from the expression context. This is the same
way expansion is done for element type names in start and end-tags
except that the default namespace declared with xmlns is not used: if
the QName does not have a prefix, then the namespace URI is null"
Therefore the template rule above is matching elements that are in "no namespace", but the elements of the XML document are in the "urn:jboss:domain:1.1" namespace -- therefore not a single node is matched by the above rule.

Saxon Transformerfactory placing unneceary xmlns:xsd="http://www.w3.org/2001/XMLSchema" in transformer output

I am using Sax transformer factory to do an XSLT transformation on large set of xsd files, so a particular line the xslt is as follows.
<xsl:result-document href="{$fileName}"
doctype-public="-//OASIS//DTD DITA Reference//EN"
doctype-system="reference.dtd">
<reference id="{$guid}" xml:lang="EN-US" outputclass="landscape">
<title>
<xsl:value-of select="$typeName"/>
</title>
<abstract>....
the reference tag being the root of the document, but the result has an unwanted xmlns:xsd attribute shown below.
...<reference xmlns:xsd="http://www.w3.org/2001/XMLSchema"
id="RANDOM-ID".....
this additional attribute is causing problems with parser that uses the transformed xml.
is this an issue with the XSLT or with SAXON api, how can i avoid this?
By default the xsl transformation will copy namespaces that are defined in the stylesheet to the output document. You can exclude this namespace by specifying the exclude-result-prefixes on the xsl:stylesheet or the reference element with a value of "xsd".
Here is the relevant part of the xslt sepcification:
The created element node will also have a copy of the namespace nodes that were present on the element node in the stylesheet (...)
A namespace URI is designated as an excluded namespace by using an exclude-result-prefixes attribute on an xsl:stylesheet element or an xsl:exclude-result-prefixes attribute on a literal result element. The value of both these attributes is a whitespace-separated list of namespace prefixes.

Local XML namespace definition not working as I expected

I'm processing an XMI document exported from ArgoUML. It has elements of the form
<UML:DataType href='http://argouml.org/profiles/uml14/default-uml14.xmi#-84-17--56-5-43645a83:11466542d86:-8000:000000000000087C'/>
which points to an item of the form
<UML:DataType xmi.id="-84-17--56-5-43645a83:11466542d86:-8000:000000000000087C"
name="Integer"
isSpecification="false"
isRoot="false"
isLeaf="false"
isAbstract="false"/>
I've already declared xmlns:UML="org.omg.xmi.namespace.UML" at the top of the xslt file. I think I should be using something like :
<xsl:variable name="typeref" select="#href"/>
<xsl:variable name="ns" select='substring-before($typeref, "#")'/>
<xsl:variable name="identifier" select='substring-after($typeref, "#")'/>
<xsl:value-of xmlns:UML="$ns"
select='//UML:DataType[#xmi.id="$identifier"]/#name'/>
to deduce that my UML attributes type is Integer but this gives me
SystemId Unknown; Line #136; Column #94; A location step was expected following the '/' or '//' token.
If I change the xmlns to AAA then I get no error but an empty tag. I'm using Xalan2 on Debian squeeze. What am I missing?
Don't mind me. Just making the classic mistake of conflating namespaces and URIs. What I really needed was <xsl:value-of select='document($ns)//UML:DataType[#xmi.id=$identifier]/#name'/>