Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

XPath filter with local-name() in attribute?

5 views
Skip to first unread message

Thomas Malia

unread,
Jul 18, 2006, 1:43:54 PM7/18/06
to
OK, I've got an XML document that has nodes that look like the following:
<APDoc ToAcctAP:DataSourceEntityID="12345" ToAcctAP:DataSourceID="DMS_FIELD"
xsi:type="ToAcctAP:ToAcctAPDoc_Type" ToAcctAP:DMSDocType="PAYMENT_TO_OTHER">
<ToAcctAP:AcctAddress>
<ToAcctAP:Name>T&amp;T Data Solutions</ToAcctAP:Name>
<ToAcctAP:Attn/>
<ToAcctAP:Salut/>
<ToAcctAP:Addr1>710 Ruddy Court</ToAcctAP:Addr1>
<ToAcctAP:Addr2/>
<ToAcctAP:City xsi:nil="true"/>
<ToAcctAP:State>MD</ToAcctAP:State>
<ToAcctAP:ZIP xsi:nil="true"/>
<ToAcctAP:Country>abZ</ToAcctAP:Country>
<ToAcctAP:Phone>TED</ToAcctAP:Phone>
<ToAcctAP:Fax></ToAcctAP:Fax>
<ToAcctAP:EMailAddr/>
</ToAcctAP:AcctAddress>
<ToAcctAP:InvoiceDate xsi:nil="true"/>
<ToAcctAP:Descr/>
<ToAcctAP:DocAmt>100</ToAcctAP:DocAmt>
</APDoc>

an XPath expression like:
"*[local-name()='ToAccountingAPDocuments']/*[local-name()='APDoc']"
is giving me a node list of all the APDoc elements. Now I want to be able
to select subsets of this set based in the value of the
"ToAcctAP:DMSDocType" attribute of the APDoc elements. I can't seem to
figure out the correct syntax for this filter. Everything I try either
leaves me with an empty set or throws an error when trying to parse the
xpath expression.

HELP!


George Bina

unread,
Jul 19, 2006, 3:24:18 AM7/19/06
to
If you do not want to use prefixes to test exactly for the DMSDocType
from the namespaces mapped to the ToAccAP prefix then you can use again
local-name as below:

/*[local-name()='ToAccountingAPDocuments']/*[local-name()='APDoc' and
'PAYMENT_TO_OTHER'=@*[local-name()='DMSDocType']]

Best Regards,
George
---------------------------------------------------------------------
George Cristian Bina
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com

Thomas Malia

unread,
Jul 19, 2006, 9:03:36 AM7/19/06
to
Thanks a lot. that's working great.

As a follow up comment, I hope this doesn't offend anyone here but I was
discussion XPATH and XSLT with a collegue, both of us have extensive
experience in the SQL world and are now trying to come to grips with the XML
world. I realize there are fundimental differences between relational
verses hierarchical data and that requires different approaches, but...
here's a brief exchange this friend and I had. :

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

[My Friend] For the life of me, I can't understand why XPATH could not be
more like SQL. Did we really have to invent a whole new syntax?

[Tom Malia] Here! Here! I've been say exactly the same thing myself. It's
like the whole XML community has this aversion to anything that vaguely
looks like the English language (which is really ironic since the original
intent and I believe still stated requirement for the XML standard is that
it must be human readable) and an affinity for everything arcane and
cryptic. It's like the "bad old days" of C when programmers took great
pride in writing code with the fewest possible key strokes.

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

I should qualify this by saying, in this exchange, I am tlaking specifically
about things like XPath and XSLT and I regular expressions, not really about
XML documents themselves. It's almost like we're trying to compensate for
the "excessive" wordiness of XML by following an excessivly reductionist
approach to the Query and Definition languages. Though as I'm typing this,
I'm recalling that much of this stuff looks like things I use to see in UNIX
and I supose that might explain a lot of it.

"George Bina" <geo...@oxygenxml.com> wrote in message
news:1153293858....@s13g2000cwa.googlegroups.com...

Anthony Jones

unread,
Jul 20, 2006, 4:40:28 AM7/20/06
to

"Thomas Malia" <tomm...@worldnet.att.net> wrote in message
news:eW3wUOzq...@TK2MSFTNGP03.phx.gbl...

> Thanks a lot. that's working great.
>
> As a follow up comment, I hope this doesn't offend anyone here but I was
> discussion XPATH and XSLT with a collegue, both of us have extensive
> experience in the SQL world and are now trying to come to grips with the
XML
> world. I realize there are fundimental differences between relational
> verses hierarchical data and that requires different approaches, but...
> here's a brief exchange this friend and I had. :
>
> --------------------------------------------------------------------------
----------------------------------------------------------------------------
-------------
>
> [My Friend] For the life of me, I can't understand why XPATH could not be
> more like SQL. Did we really have to invent a whole new syntax?
>
> [Tom Malia] Here! Here! I've been say exactly the same thing myself. It's
> like the whole XML community has this aversion to anything that vaguely
> looks like the English language (which is really ironic since the original
> intent and I believe still stated requirement for the XML standard is that
> it must be human readable) and an affinity for everything arcane and
> cryptic. It's like the "bad old days" of C when programmers took great
> pride in writing code with the fewest possible key strokes.
>

I don't think your analog of XPath to C is really that valid. I spent much
of my career writing to VB and SQL but I don't find XPath to be that
cryptic. It is natural for us to want things that, in our mental model, are
similar to be accessed and manipulated by similar concepts.

The reality is that for one thing, things aren't as similar as we might
think they are. As you alluded to SQL and XPath are designed to query very
different data structures and frankly SQL is a far richer environment than
XPath was intended to be.

Another thing is that XML/XPath are much younger than SQL and having very
different foundations it would have made no sense to use SQL as some kind of
basis for early XPath specifications. It takes time for these community
driven standards to develop.

Yet another thing is that the so called cryptic style of
C,C++,C#,Java,Javascript,Unix etc., etc, is still popular with many
developers and they might criticise an overly verbose or perponderous
syntax. Hence XPath is bound to receive criticisim.

We have XPath 2.0 and XQuery now teetering on the edge of wider use. These
perhaps will be more to your liking.

The crux of the problem is the 'mental model'. I found that once I had
understood the 'internals' of XML, XPath became more natural before that I
struggled as you seem to be with the syntax. What helped me was getting to
grips with the concept of axis in XPath, that really helps show how
different querying XML is to relational data and how an XPath moves from one
node to another.

> --------------------------------------------------------------------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------

Thomas Malia

unread,
Jul 24, 2006, 5:05:40 PM7/24/06
to
This stuff is still driving me nuts!

given the same structure as before, and assuming there are multiple APDoc
Type elements:


<APDoc ToAcctAP:DataSourceEntityID="12345" ToAcctAP:DataSourceID="DMS_FIELD"
xsi:type="ToAcctAP:ToAcctAPDoc_Type" ToAcctAP:DMSDocType="PAYMENT_TO_OTHER">
<ToAcctAP:AcctAddress>
<ToAcctAP:Name>T&amp;T Data Solutions</ToAcctAP:Name>
<ToAcctAP:Attn/>
<ToAcctAP:Salut/>
<ToAcctAP:Addr1>710 Ruddy Court</ToAcctAP:Addr1>
<ToAcctAP:Addr2/>
<ToAcctAP:City xsi:nil="true"/>
<ToAcctAP:State>MD</ToAcctAP:State>
<ToAcctAP:ZIP xsi:nil="true"/>
<ToAcctAP:Country>abZ</ToAcctAP:Country>
<ToAcctAP:Phone>TED</ToAcctAP:Phone>
<ToAcctAP:Fax></ToAcctAP:Fax>
<ToAcctAP:EMailAddr/>
</ToAcctAP:AcctAddress>
<ToAcctAP:InvoiceDate xsi:nil="true"/>
<ToAcctAP:Descr/>
<ToAcctAP:DocAmt>100</ToAcctAP:DocAmt>
</APDoc>

How the heck do I structure an xpath query that would giving me something
like, a node list of all APDoc elements where the
ToAcctAP:AcctAddress/ToAcctAP:State = 'NJ' ?

It the darn namespaces that I think are killing me!!!! without them,
wouldn't it just be something like:
"/APDoc[AcctAddress/State='NJ']"

I'm so confused.


"George Bina" <geo...@oxygenxml.com> wrote in message
news:1153293858....@s13g2000cwa.googlegroups.com...

George Bina

unread,
Jul 25, 2006, 4:38:47 AM7/25/06
to
Hi Thomas,

How exactly do you have "multiple APDoc Type elements"? Embedded in
another element that is the document root element? In that case then an
expression like
/APDoc[...some test...]
will give you no results as this selects a document root element with
the name APDoc and that satisfies also the tests inside brackets. Try
something like
//APDoc[ToAcctAP:AcctAddress/ToAcctAP:State='NJ']

Note that your sample document is not XML (it is not wellformed).

Thomas Malia

unread,
Jul 25, 2006, 9:23:46 AM7/25/06
to
Sorry... the XML I included was a "snippet" there is one more level above
the ARDoc level that I forgot to include in the snippet.

Regarding your suggestion, my problem is whenever I try to use the fully
qualified names with the namespace included I get
"reference to undeclared namespace prefix "ToAcctAP"

I've been able to use the local-name() function for some of the XPath
queries I've needed to build, but can't figure out how to use that function
to do the equivalent to what you have suggested here.

"George Bina" <geo...@oxygenxml.com> wrote in message

news:1153816727.7...@75g2000cwc.googlegroups.com...

Martin Honnen

unread,
Jul 25, 2006, 9:35:03 AM7/25/06
to

Thomas Malia wrote:


> Regarding your suggestion, my problem is whenever I try to use the fully
> qualified names with the namespace included I get
> "reference to undeclared namespace prefix "ToAcctAP"

If you are using MSXML then you need to do e.g.
xmlDocument.setProperty "SelectionNamespaces", _
"xmlns:pf1='http://example.com/ns1' xmlns:pf2='http://example.com/ns2'"
before you can use the prefixes pf1 and pf2 in XPath expressions passed
to selectNodes/selectSingleNode.

With .NET you need to use an XmlNamespaceManager.


--

Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/

Thomas Malia

unread,
Jul 25, 2006, 9:54:40 AM7/25/06
to
Thanks,

I guess I'm really spooled by inteli-sense... Methods like setProperty where
you just have to know all the magic codes leave my so frustrated these
days... I've almost completely forgotten the bad old days of programming
when you actually had to read books and remember all the available API calls
to be able to use them.

Next question though... is there a way to dynamically determine the URI's of
the namespaces that are declared in the XML file? I'd imagine I'll want to
have some error trapping code that checks to see if the namespaces being
used in the actual XML file match what I'm expecting in the code that's
processing it... I can also foresee the need to check which namespaces are
being used in the XML then possibly processing the file differently based on
what I find there.

Thanks again,
Tom Malia

"Martin Honnen" <maho...@yahoo.de> wrote in message
news:uDVWn8%23rGH...@TK2MSFTNGP05.phx.gbl...

Martin Honnen

unread,
Jul 25, 2006, 11:55:42 AM7/25/06
to

Thomas Malia wrote:


> Next question though... is there a way to dynamically determine the URI's of
> the namespaces that are declared in the XML file?

Yes, you can do that with XPath and the namespace axis which you can
look at with selectNodes (or of course XSLT if you use that).
In the XPath data model each node has associated namespace nodes.
Depending on what you are looking for or how your input XML is marked up
with namespaces it often suffices to look at the root element e.g.

Set NamespaceNodes =
XmlDocument.documentElement.selectNodes("namespace::*")
For Each NamespaceNode In NamespaceNodes
WScript.Echo "URI: " & NamespaceNode.nodeValue
Next

With the example

<root xmlns="http://example.com/ns1"
xmlns:pf1="http://example.com/ns2"
xmlns:pf2="http://example.com/ns3">
</root>

the output is then

URI: http://www.w3.org/XML/1998/namespace
URI: http://example.com/ns1
URI: http://example.com/ns2
URI: http://example.com/ns3

so you see that besides the declared namespaces the namespace
http://www.w3.org/XML/1998/namespace is (always) in scope.

If you want to look at all nodes and eliminate duplicates then you can
do e.g.

Set NamespaceNodes = _
XmlDocument.selectNodes("//namespace::*[not(. = ../../namespace::*)]")
For Each NamespaceNode In NamespaceNodes
WScript.Echo "URI: " & NamespaceNode.nodeValue
Next

which for instance for the input XML

<root xmlns="http://example.com/ns1"
xmlns:pf1="http://example.com/ns2"
xmlns:pf2="http://example.com/ns3">
<pf3:element xmlns:pf3="http://example.com/ns4"
xmlns:pf1="http://example.com/ns5">
<pf1:element />
</pf3:element>
</root>

will find

URI: http://www.w3.org/XML/1998/namespace
URI: http://example.com/ns1
URI: http://example.com/ns2
URI: http://example.com/ns3
URI: http://example.com/ns4
URI: http://example.com/ns5

0 new messages