XML Editor
Sign up for a WebBoard account Sign Up Keyword Search Search More Options... Options
Chat Rooms Chat Help Help News News Log in to WebBoard Log in Not Logged in
Show tree view Topic
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Postnext
Neal WaltersSubject: XPath with the noprefix namespace
Author: Neal Walters
Date: 25 Jan 2006 08:20 PM
You have helped me a lot before with similar issues!

I generate the following XPATH in Stylus Studio

/*[local-name()='OrderPartitionResponse' and namespace-uri()='http://schemas.compassion.com/order/partitionresponse/2006-01-01']/*[local-name()='Orders' and namespace-uri()='http://schemas.compassion.com/order/partitionresponse/2006-01-01'][1]/*[local-name()='Order' and namespace-uri()='http://schemas.compassion.com/order/2006-01-01'][1]

Now I want to change it to
Count nodes where OrderPartitionStatusCode = "InventoryExceptionsOnly"
(and this is one element under Order)

So first I have just an Xpath question.

If there were no namespace it would simple like this:
Simplified version: count(//OrderPartitionResponse/Order[OrderPartitionStatusCode="InventoryExceptionsOnly"])

I'm a little confused how to do this with the fully qualified names, I have tried this, and it returns a count of 0 or 1, but the count doesn't seem to match exactly the data I am querying.

count(/*[local-name()='OrderPartitionResponse' and namespace-uri()='http://schemas.compassion.com/order/partitionresponse/2006-01-01']/*[local-name()='Orders' and namespace-uri()='http://schemas.compassion.com/order/partitionresponse/2006-01-01'][1]/*[local-name()='OrderPartitionStatusCode' and namespace-uri()='http://schemas.compassion.com/order/2006-01-01'="InventoryExceptionsOnly"])

Sample Data (Eventually I could have many types of orders, and I want to count and see what I've got):

<?xml version="1.0" encoding="utf-8"?>
<OrderPartitionResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.compassion.com/order/partitionresponse/2006-01-01">
<Orders>
<Order xmlns="http://schemas.compassion.com/order/2006-01-01">
<RequestDate>2006-01-10T13:15:00.0000000-07:00</RequestDate>
<OrderPartitionStatusCode>InventoryExceptionsOnly</OrderPartitionStatusCode>
<SpecialInstruction>Whatever</SpecialInstruction>
<Profile PartnerCountryCode="US" SponsorNumber="12345" TrustLevel="Validated" xmlns="http://schemas.compassion.com/constituent/profile/profile/2005-03-01">
<Name>John Doe</Name>
<BusinessGroup xsi:nil="true" />
<Address1>827 Main Street</Address1>
<City>Crown City</City>
<CountryDivision>IN</CountryDivision>
<Country>US</Country>
<PostalCode>463073732</PostalCode>
<HomePhone Preferred="true">2195551234</HomePhone>
<WorkPhone Preferred="false" />
<CellPhone Preferred="false" />
<PreferredEmail EmailType="Personal">abc@yahoo.com</PreferredEmail>
</Profile>
<OrderItems>
<OrderItem xmlns="http://schemas.compassion.com/order/orderitem/2006-01-01">
<Quantity>5</Quantity>
<ItemNumber>Kit55</ItemNumber>
<ItemDescription>Compassion Countertop Displays with Brochures</ItemDescription>
<IsKit>true</IsKit>
</OrderItem>
</OrderItems>
</Order>
</Orders>
</OrderPartitionResponse>

You know what would be a really cool feature?
Let me type in my xpath like this:
Simplified version: count(//OrderPartitionResponse/Order[OrderPartitionStatusCode="InventoryExceptionsOnly"])

then you convert it to the full syntax!
Or I guess I could add the prefix, but that might require some extra CPU cycles (I may not have a choice of how I receive the data).

Thanks again,
Neal Walters
http://Biztalk-Training.com



Postnext
Tony LavinioSubject: XPath with the noprefix namespace
Author: Tony Lavinio
Date: 26 Jan 2006 11:04 AM
The easiest way I think is to go to tree view,
right click on OrderPartitionStatusCode,
choose Copy XPath Query To Clipboard,
paste it into the XPath search bar, and finally
replace the [1] at the end with [. = 'InventoryExceptionsOnly']

If you want the count, you can then surround the whole thing
with count( and ).

Postnext
Neal WaltersSubject: XPath with the noprefix namespace
Author: Neal Walters
Date: 26 Jan 2006 12:28 PM
THANKS!

Even though I have been using this syntax for a year - I just really dawned on me that the whole expression is a bunch of where clauses (in square brackets).

Add the additional where clause to test for a value was really confusing me, so your answer: [. = 'InventoryExceptionsOnly']
worked fine, which I presume means - test the value of the currently selected node for 'InventoryExceptionsOnly'.

count(/*[local-name()='OrderPartitionResponse' and namespace-uri()='http://schemas.compassion.com/order/partitionresponse/2006-01-01']/*[local-name()='Orders' and namespace-uri()='http://schemas.compassion.com/order/partitionresponse/2006-01-01'][1]/*[local-name()='Order' and namespace-uri()='http://schemas.compassion.com/order/2006-01-01'][1]/*[local-name()='OrderPartitionStatusCode' and namespace-uri()='http://schemas.compassion.com/order/2006-01-01'][. = 'InventoryExceptionsOnly'])

A co-worker showed me today that you can actually leave out the namespaces clauses as long as you dont' have conficts, so this works equally well in our case:

count(/*[local-name()='OrderPartitionResponse']/*[local-name()='Orders'][1]/*[local-name()='Order'][1]/*[local-name()='OrderPartitionStatusCode'][. = 'InventoryExceptionsOnly'])

Thanks again,
Neal Walters
http://Biztalk-Training.com



Postnext
Neal WaltersSubject: XPath with the noprefix namespace
Author: Neal Walters
Date: 31 Jan 2006 05:04 PM
Ok, so now I want to use Xpath to extract the Order node of all orders where OrderPartitionStatusCode = 'NoExceptions'.

I think I have an "axis" issue.

I'm used to something like this /PartitionOrder/Orders/Order[OrderPartitionStatusCode='NoExceptions'].

In this case, it is clear that the node I want is Order and that the predicate or "where clause" is on the variable.

When I try this:
/*[local-name()='OrderPartitionResponse' and namespace-uri()='http://schemas.compassion.com/order/partitionresponse/2006-01-01']/*[local-name()='Orders' and namespace-uri()='http://schemas.compassion.com/order/partitionresponse/2006-01-01'][1]/*[local-name()='Order' and namespace-uri()='http://schemas.compassion.com/order/2006-01-01'][1]/*[local-name()='OrderPartitionStatusCode' and namespace-uri()='http://schemas.compassion.com/order/2006-01-01'][. = 'InventoryExceptionsOnly']

then I get only the OrderPartitionNode, but I need the entire Order node.

It's unclear what is my "context node" and my axis - I was looking at this great page: http://www.stylusstudio.com/docs/v2006/d_xpath89.html


Thanks again,
Neal Walters

Postnext
Neal WaltersSubject: XPath with the noprefix namespace
Author: Neal Walters
Date: 31 Jan 2006 05:20 PM
I'm trying to think through this, if I didn't have the no-namespace issue, my Xpath would simply be this:

/OrderPartitionResponse/Orders/Order[OrderPartitionStatusCode="InventoryExceptionsOnly"]

So this means select all "order" nodes where a child element has some specific value. I'm guessing Order is my "context node".

against this data:
<OrderPartitionResponse>
<Orders>
<Order>
<RequestDate>2006-01-10T13:15:00.0000000-07:00</RequestDate>
<OrderPartitionStatusCode>InventoryExceptionsOnly</OrderPartitionStatusCode>
</Order>
</Orders>
</OrderPartitionResponse>


The same data with the namespaces looks like this:
<OrderPartitionResponse xmlns="http://schemas.compassion.com/order/partitionresponse/2006-01-01">
<Orders>
<Order xmlns="http://schemas.compassion.com/order/2006-01-01">
<RequestDate>2006-01-10T13:15:00.0000000-07:00</RequestDate>
<OrderPartitionStatusCode>InventoryExceptionsOnly</OrderPartitionStatusCode>
</Order>
</Orders>
</OrderPartitionResponse>




If I just said /OrderPartitionResponse that is same as
/child::OrderPartitionResponse.

So could we walk through what this XPATH means?

/*[local-name()='OrderPartitionResponse']/*[local-name()='Orders'][1]/*[local-name()='Order'][1]/*[local-name()='OrderPartitionStatusCode'][. = 'InventoryExceptionsOnly']

When I run this, this selects the node that contains OrderPartitionStatusCode (including its value).

Since it starts with a /, that means start at the top of the document, then immediately I see *[xxx], so that means find all nodes where the thing in the brackets is true. Presumabley local-name() means find any element-name that matches the name of OrderPartitionResponse.

So I'm already confused where my axis and content node are.

As to the end, the [. = 'InventoryExceptionsOnly'] the "." means the context node, so it is selecting the context node where it's value is "InventoryExceptionsOnly". So that is why the OrderPartitionStatusCode is selected in the output.

Now, how do I select one node higher for the output, but still limit or filter based upon this type of criteria:
[OrderPartitionStatusCode="InventoryExceptionsOnly"]


Thanks again,
Neal




Postnext
Tony LavinioSubject: XPath with the noprefix namespace
Author: Tony Lavinio
Date: 31 Jan 2006 09:11 PM
The cheap way would be to add /.. to the end.

But let's do it more intelligently.

Looking at the XPath of

/*[local-name()='OrderPartitionResponse']/*[local-name()='Orders'][1]/*[local-name()='Order'][1]/*[local-name()='OrderPartitionStatusCode'][. = 'InventoryExceptionsOnly']

What this means is:

/ - starting from the root
* - select all elements at this level
[local-name()='OrderPartitionResponse'] - that have this local name
/ - switch our context to the children of the elements that match the above
* - select all elements at this level
[local-name()='Orders'] - that have a local name of "Orders"
[1] - and take the first one of that set
/ - switch our context to the children of the elements that match this point so far
* - select all elements at this level
[local-name()='Order'] - and filter out all that aren't 'Order'
[1] - and of those, just take the first
/ - and again, switch our context to children of the above
* - of these, select all of the elements
[local-name()='OrderPartitionStatusCode'] - filter just down to these
[. = 'InventoryExceptionsOnly'] - and of those, select the ones with this value.

Now, we could make Order your context by fiddling with the path a
little. Remember that we can do multiple tests within the [ and ], and
that they DON'T change your context. So you can do this:

[local-name() = 'Order' and ./*[local-name()='OrderPartitionStatusCode'][. = 'InventoryExceptionsOnly']]

Note the nested [ ] expressions? Pretty cool, huh?

An XPath that would select all of the Order elements that have a
OrderPartitionStatusCode of "InventoryExceptionsOnly" would look
like this:

/*[local-name()='OrderPartitionResponse']/*[local-name()='Orders']/*[local-name() = 'Order' and ./*[local-name()='OrderPartitionStatusCode'][. = 'InventoryExceptionsOnly']]

Postnext
Neal WaltersSubject: XPath with the noprefix namespace
Author: Neal Walters
Date: 01 Feb 2006 12:51 PM
Tony - Thanks a million! Your explanation was great.

Neal

Postnext
Neal WaltersSubject: XPath with the noprefix namespace
Author: Neal Walters
Date: 17 Feb 2006 04:10 PM
Okay, here's one I'm proud of. Your prior example helped a lot!

That xml data contains a series of name/value pairs(also known as hash table or sometimes a "dictionary"). I needed to find (count) if there any of the value of a certain variable were equal to a certain value.

count(/*[local-name()='UltimusWorkflowResponse']/Payload/*[local-name()='UltimusIncidentResponse']/*[local-name()='LocalVariables' and namespace-uri()='http://schemas.compassion.com/ultimus/ultimusincidentresponse/2005-03-01']/*[local-name()='LocalVariable' and @VarName='gArrSelectedActionTypeCode']/*[local-name()='VarValue'][.='PROFILEUPDATE'])



<ns0:UltimusWorkflowResponse SchemaVersion="1.0" xmlns:ns0="http://Compassion.BizTalk.Schemas.Ultimus.CIUltimusWorkflowResponse" xmlns:ult="http://schemas.compassion.com/ultimus/ultimusincidentresponse/2005-03-01">
<CancelFlag>false</CancelFlag>
<ResponseCode>ConCreated</ResponseCode>
<Payload>
<ult:UltimusIncidentResponse ProcessId="708e882a-48c0-4f33-8f24-b84e3f7e7ae1" ProcessName="ReconcileConException">
<ns0:LocalVariables xmlns:ns0="http://schemas.compassion.com/ultimus/ultimusincidentresponse/2005-03-01">
<ns0:LocalVariable VarName="gStreamID">
<ns0:VarValue>c2f9025a-3d07-4a10-9704-727feb720129</ns0:VarValue>
</ns0:LocalVariable>
<ns0:LocalVariable VarName="gMessageID">
<ns0:VarValue>d136969f-2932-4a4e-87be-049fb931332c</ns0:VarValue>
</ns0:LocalVariable>
<ns0:LocalVariable VarName="gUpdatePartnerCountry">
<ns0:VarValue>US</ns0:VarValue>
</ns0:LocalVariable>
<ns0:LocalVariable VarName="gUpdateConID">
<ns0:VarValue>2002158</ns0:VarValue>
</ns0:LocalVariable>
<ns0:LocalVariable VarName="gReturnCode">
<ns0:VarValue>ConCreated</ns0:VarValue>
</ns0:LocalVariable>
<ns0:LocalVariable VarName="gArrSelectedActionTypeCode">
<ns0:VarValue>PROFILETEST1</ns0:VarValue>
</ns0:LocalVariable>
<ns0:LocalVariable VarName="gArrSelectedActionTypeCode">
<ns0:VarValue>PROFILEUPDATE</ns0:VarValue>
</ns0:LocalVariable>
<ns0:LocalVariable VarName="gArrSelectedActionTypeCode">
<ns0:VarValue>PROFILETEST2</ns0:VarValue>
</ns0:LocalVariable>
</ns0:LocalVariables>
</ult:UltimusIncidentResponse>
</Payload>
</ns0:UltimusWorkflowResponse>

Neal Walters
http://Biztalk-Training.com

Posttop
Neal WaltersSubject: XPath with the noprefix namespace
Author: Neal Walters
Date: 26 Aug 2007 09:03 PM
It's only about once a year I have to write a difficult XPath.
I have the 2007 Enterprise version of Stylus Studio, and would be so great to have a helper utility to help write these Xpaths by now.

Here's my XML:

<HipaaClaimTrigger xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://TIE.HSD.Primary.Medicaid.Schemas.schHipaaTrigger">
<ProviderSubmitterGroup>
<ProviderSubmitterItems ProviderId="000A0025" SubmitterId="2" SubmitterDirName="Test Only"/>
<ProviderSubmitterItems ProviderId="000A4071" SubmitterId="4" SubmitterDirName="Test"/>
<ProviderSubmitterItems ProviderId="000A1184" SubmitterId="6" SubmitterDirName="Testuser"/>
<ProviderSubmitterItems ProviderId="000K2125" SubmitterId="2" SubmitterDirName="Test Only"/>
<ProviderSubmitterItems ProviderId="000Z9862" SubmitterId="4" SubmitterDirName="Test"/>
<ProviderSubmitterItems ProviderId="000A0116" SubmitterId="6" SubmitterDirName="Testuser"/>
</ProviderSubmitterGroup>
</HipaaClaimTrigger>

This XPath returns two nodes:
/*[local-name()='HipaaClaimTrigger']/*[local-name()='ProviderSubmitterGroup']/*[local-name()='ProviderSubmitterItems']/@*[local-name()='SubmitterDirName'][.='Test']

But I want to test on the SubmitterId not the SubmitterDirName, so the first question: I want to get all the nodes where SubmitterId='2'

Here's my current attempt:

/*[local-name()='HipaaClaimTrigger']/*[local-name()='ProviderSubmitterGroup']/*[local-name()='ProviderSubmitterItems'][@SubmitterId='2']/@SubmitterDirName

This works and returns two nodes (which have the same values).

But since submitters have the same SubmitterDirName, I just want to get the first match, and this seems to work:

/*[local-name()='HipaaClaimTrigger']/*[local-name()='ProviderSubmitterGroup']/*[local-name()='ProviderSubmitterItems'][@SubmitterId='2'][1]/@SubmitterDirName

Cheers!
Neal Walters
http://Biztalk-Training.com
http://CMSTrainingVideos.com










 
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Download A Free Trial of Stylus Studio 6 XML Professional Edition Today! Powered by Stylus Studio, the world's leading XML IDE for XML, XSLT, XQuery, XML Schema, DTD, XPath, WSDL, XHTML, SQL/XML, and XML Mapping!  
go

Log In Options

Site Map | Privacy Policy | Terms of Use | Trademarks
Stylus Scoop XML Newsletter:
W3C Member
Stylus Studio® and DataDirect XQuery ™are from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2016 All Rights Reserved.