ancestor:: XML syntax

J

John Bailo

Is anyone familar with the correct syntax for using ancestor:: ?

I am trying to use it in a c# application, and I am also testing it in a
parser application called Cooktop ( http://www.xmlcooktop.com )

I cannot get it or my c# code to return a node list when using ancestor.
Is ancestor:: something that .NET does or does not support?

Examples, none of these work:

nodes://pallet/ancestor::position
<!--nodes xpath //pallet/ancestor::position'-->
<!--nodes xpath parent::*/pallet/position/*'-->
<!--nodes xpath parent::*//pallet/position/*'-->
<!--nodes xpath /ancestor::position/client[@id='MDR']'-->
<!--nodes xpath /pallet/ancestor::position/client[@id='MDR']'-->
<!--nodes xpath /pallet/position/ancestor::client[@id='MDR']'-->

for


<pallet>
<position row="0" bay="0" level="A">
<client id="HAL">
<partnum id="HA0132-1033 " isStock="N">HA0132-1033 </partnum>
<partnum id="HA9027EP " isStock="Y">HA9027EP </partnum>
</client>
<client id="MDR">
<partnum id="A/P FILES " isStock="N">A/P FILES </partnum>
</client>
<client id="OPS">
<partnum id="OPS " isStock="N">OPS
</partnum></client>
</position>
<position row="1" bay="1" level="B">
<client id="MDR">
<partnum id="A/P FILES " isStock="N">A/P FILES
</partnum>
</client>
</position>
<position row="1" bay="1" level="D">
<client id="MDR">
<partnum id="X-MAS DECORATION" isStock="N">X-MAS DECORATION
</partnum>
</client>
</pallet>
 
M

Martin Honnen

John Bailo wrote:

Examples, none of these work:

nodes://pallet/ancestor::position

<pallet>
<position row="0" bay="0" level="A">
<client id="HAL">
<partnum id="HA0132-1033 " isStock="N">HA0132-1033 </partnum>
<partnum id="HA9027EP " isStock="Y">HA9027EP </partnum>
</client>
<client id="MDR">
<partnum id="A/P FILES " isStock="N">A/P FILES </partnum>
</client>
<client id="OPS">
<partnum id="OPS " isStock="N">OPS
</partnum></client>
</position>
<position row="1" bay="1" level="B">
<client id="MDR">
<partnum id="A/P FILES " isStock="N">A/P FILES
</partnum>
</client>
</position>
<position row="1" bay="1" level="D">
<client id="MDR">
<partnum id="X-MAS DECORATION" isStock="N">X-MAS DECORATION
</partnum>
</client>
</pallet>

The position elements are children of the pallet element so I don't
understand why you want
//pallet/ancestor::position
If you want to access the position elements then you need
/pallet/position
 
G

Greg Collins [Microsoft MVP]

It looks like you are wanting to use descendant:: rather than ancestor::
 
J

John Bailo

Martin said:
The position elements are children of the pallet element so I don't
understand why you want
//pallet/ancestor::position
If you want to access the position elements then you need
/pallet/position

So, I want to return all the POSITION nodes that contain CLIENTS whose
id is MDR.

But the only children of POSITION I want are the CLIENTS whose id is MDR.

If I do

/pallet/position/client[@id='MDR']/..

I get all the POSITIONS, but all CLIENTS in those positions, not just
CLIENTS whose id = 'MDR'

So, from my example XML, if I did an xpath to isolate @id='MBR', I would
like this to be my return list:

<pallet>
<position row="0" bay="0" level="A">
<client id="MDR">
<partnum id="A/P FILES " isStock="N">A/P FILES </partnum>
</client>
</position>
<position row="1" bay="1" level="B">
<client id="MDR">
<partnum id="A/P FILES " isStock="N">A/P FILES
</partnum>
</client>
</position>
<position row="1" bay="1" level="D">
<client id="MDR">
<partnum id="X-MAS DECORATION" isStock="N">X-MAS DECORATION
</partnum>
</client>
</pallet>

That's why I thought I'd use ancestor, to find all the clientnodes, and
then each client node's ancestor (which I think will exclude the other
child nodes of each position node).
 
M

Martin Honnen

John Bailo wrote:

If I do

/pallet/position/client[@id='MDR']/..

I get all the POSITIONS, but all CLIENTS in those positions, not just
CLIENTS whose id = 'MDR'

So, from my example XML, if I did an xpath to isolate @id='MBR', I would
like this to be my return list:

XPath 1.0 selects existing nodes in the input document, it can't change
the structure of the original document. If you use
/pallet/position/client[@id='MDR']
you select the client elements with id attribute value 'MDR'.
If you want to filter out child nodes of the pallet root element but
still have that root around then you need an XSLT stylesheet to do that,
XPath alone does not help.
 
J

John Bailo

Can the result of an XSLT transformation be a NodeList? Or XmlDocument?

Or is XSLT for display (*.html) purposes only?

Martin said:
John Bailo wrote:

If I do

/pallet/position/client[@id='MDR']/..

I get all the POSITIONS, but all CLIENTS in those positions, not just
CLIENTS whose id = 'MDR'

So, from my example XML, if I did an xpath to isolate @id='MBR', I
would like this to be my return list:


XPath 1.0 selects existing nodes in the input document, it can't change
the structure of the original document. If you use
/pallet/position/client[@id='MDR']
you select the client elements with id attribute value 'MDR'.
If you want to filter out child nodes of the pallet root element but
still have that root around then you need an XSLT stylesheet to do that,
XPath alone does not help.
 
J

John Bailo

John said:
Can the result of an XSLT transformation be a NodeList? Or XmlDocument?

Or is XSLT for display (*.html) purposes only?

Ok, looks like the answer is /yes/.

Here is some sample code I found that will output an XML text stream:

http://www.xmlforasp.net/CodeSection.aspx?csID=103

using System;
using System.Diagnostics;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;

public class TransformXML
{
//This will transform xml document using xslt
//and produce result xml document
//and display it
public static void Main(string[] args)
{
//args[0]--xmldocument; [1]--xsl;
try {
StringWriter sw = new StringWriter();
XPathDocument xmlDoc = new XPathDocument(args[0]);
//Create XslTransform and load stylesheet
XslTransform trans1 = new XslTransform();
//Create resolver and provide evidence
trans1.Load(args[1]);
//Transform XML
trans1.Transform(xmlDoc,null,sw, new XmlUrlResolver());
Debug.WriteLine("\n\n"+sw.ToString() +"\n\n");
}
catch (Exception e)
{ Console.WriteLine ("Exception: {0}", e.ToString()); }
}}

Martin said:
John Bailo wrote:

If I do

/pallet/position/client[@id='MDR']/..

I get all the POSITIONS, but all CLIENTS in those positions, not just
CLIENTS whose id = 'MDR'

So, from my example XML, if I did an xpath to isolate @id='MBR', I
would like this to be my return list:



XPath 1.0 selects existing nodes in the input document, it can't
change the structure of the original document. If you use
/pallet/position/client[@id='MDR']
you select the client elements with id attribute value 'MDR'.
If you want to filter out child nodes of the pallet root element but
still have that root around then you need an XSLT stylesheet to do
that, XPath alone does not help.
 
M

Martin Honnen

John Bailo wrote:

Can the result of an XSLT transformation be a NodeList? Or XmlDocument?

The result of an XSLT transformation is a tree which can then be
serialized as an XML document (xsl:blush:utput method="xml") or as an HTML
document (xsl:blush:utput method="html") or as a plain text document
(xsl:blush:utput method="text"). So you can transform XML to XML with XSLT,
for instance filter output nodes in the input XML.
 
J

John Bailo

Martin said:
The result of an XSLT transformation is a tree which can then be
serialized as an XML document (xsl:blush:utput method="xml") or as an HTML
document (xsl:blush:utput method="html") or as a plain text document
(xsl:blush:utput method="text"). So you can transform XML to XML with XSLT,
for instance filter output nodes in the input XML.


Excellent.

I've been playing around with it in my c# code and you're right, it
should do what I want.

I just hope there's a programmatic way of creating the XSLT document
because my queries will be changing from run to run.

So, I guess it breaks down to

XPath is the equivalent of a SELECT statement (returns the nodes)
XSLT is the equivalent of a WHERE clause (filters the results)
 
M

Martin Honnen

John said:
So, I guess it breaks down to

XPath is the equivalent of a SELECT statement (returns the nodes)
XSLT is the equivalent of a WHERE clause (filters the results)

Certainly not as far as XSLT goes, it is much more than an WHERE clause,
XSLT is able to construct new nodes/documents and can completely change
the structure and contents of the input XML.
 
J

John Bailo

Martin said:
Certainly not as far as XSLT goes, it is much more than an WHERE clause,
XSLT is able to construct new nodes/documents and can completely change
the structure and contents of the input XML.

Well that seems to be what I need, since you've established that XPath
can't return only certain child nodes and their antecedents w/out
returning all other antecedents of their parents.
 
J

John Bailo

John said:
Martin Honnen wrote:
Well that seems to be what I need, since you've established that XPath
can't return only certain child nodes and their antecedents w/out
returning all other antecedents of their parents.

Ooops.

Make that "all other descendants of their parents".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top