2

I'm trying to select on an attribute within an XML node like this one here:

<tdf:TrustedDataObject xmlns="urn:com:bank:baml:tdf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" >

I'm able to find the node using Firepath with something like this:

/*[local-name()='TrustedDataObject']

But if I wanted to select on an attribute within the node, like the gml attribute, I'm not sure how to do this. I've tried a few different ways like:

/*[local-name()='TrustedDataObject']/@gml

or

/*[local-name()='TrustedDataObject'][gml]

And they don't match anything.

Does anybody have some suggestions? I know this isn't complete code, I don't have access to the entire document right now so I apologize.

EDIT- Ok, I wasn't sure if I should start another question or just edit my original. I understand that there are limitations when trying to access the namespace attributes, but really what I was trying to do was create a content node on the attributes in NoticeText like - ownerProducer and pocType.

<document>
   <tdf:TrustedDataObject xmlns="urn:com:bank:baml:tdf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" >
      <ism:Notice ism:classification="X" ism:ownerProducer="ABC" ism:noticeType="POC" ism:externalNotice="true">
        <ism:NoticeText ism:classification="X" ism:ownerProducer="ABC" ism:pocType="JJJ-710">John Smith, Walmart, jsmith@walmart.com</ism:NoticeText>
      </ism:Notice>
   </tdf:TrustedDataObject>
<document>

Again, I would think being able to traverse down to the NoticeText node, using local-name() should work. Something like this?

//*[local-name()='NoticeText']/@ownerProducer  

Thanks again for the help. Maybe you're telling me that all of these attributes aren't accessible via xpath...

rally_point
  • 89
  • 1
  • 1
  • 9
  • 2
    Your question is not clear. Instead of showing us code that does not do what you want, why don't you show us what the expected result is in your example (and explain why)? Note also that that the `tdf:` and `ism:` prefixes in your input are not bound to a namespace - so this is not going to work at all. – michael.hor257k Aug 22 '14 at 22:13

3 Answers3

8

In general, xpath processors allow you to register namespaces, so the xpath would be (having registered the namespaces with the same prefixes)

//ism:NoticeText/@ism:ownerProducer

For example, in XSLT you would register the namespaces in the XML of the template using namespace declarations, and then use the prefixes in the xpath expressions

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ism="urn:us:gov:ic:ism">
<xsl:template match="/">
<result>
<xsl:value-of select="//ism:NoticeText/@ism:ownerProducer">
</result>
</xsl:template>
</xsl:stylesheet>

According to this answer you can't register namespaces when using FirePath, so a work-around is to look at the local name only. Note that this may cause problems if other namespaces use the same local name - you're defeating the whole point of namespaces when you do this, so use a better tool in production code.

So to select all attributes whose local name is 'ownerProducer' from all elements whose local name is 'NoticeText' irrespective of namespace, the xpath would be

//*[local-name()='NoticeText']/@*[local-name()='ownerProducer'] 

which breaks down as

//                             a descendent of the current context
*                              any element
[local-name()='NoticeText']    whose local name is 'NoticeText'
/                              a child of the current context
@*                             any attribute
[local-name()='ownerProducer'] whole local name is 'ownerProducer'
Community
  • 1
  • 1
Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
  • 2
    +1 Also, to help alleviate any problems caused by multiple namespaces using the same local name, you can use `namespace-uri()` to make sure you match exactly what you're intending. Example: `@*[local-name()='ownerProducer' and namespace-uri()='urn:us:gov:ic:ism']` – Daniel Haley Aug 22 '14 at 21:58
2

While the XML element has three attributes, all of them are namespace declarations and in the XSLT and XPath data model namespace declarations don't appear as attributes in the tree. So with XPath you can't access those attributes, all you could do is access the namespace nodes that are in scope on the namespace axis.

See http://www.w3.org/TR/xpath/#namespace-nodes for details on namespace nodes.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
0

As gml is not an attribute as mentioned above. If still you want to access value of gml namespace in your our output. Please use the following code

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:template match="/">        
     <output> <xsl:value-of select="/*/namespace::node()[local-name()='gml']"></xsl:value-of></output>
</xsl:template>
</xsl:stylesheet>

Input :

<tdf:TrustedDataObject xmlns:tdf="urn:com:bank:baml:tdf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" >
 </tdf:TrustedDataObject>    

Output :

   <output>http://www.opengis.net/gml</output>
Isaac G Sivaa
  • 1,289
  • 4
  • 15
  • 32