C# XPath - get data without using XPathNodeIterator? Help!

G

Guest

Hi there,

I had this xml file with me (not yet consider implementing xml namespaces yet).

<?xml version='1.0'?>
<Object>
<Windows>
<EID>1</EID>
<EDesc>Error 1</EDesc>
</Windows>
<Windows>
<EID>2</EID>
<EDesc>Error 2</EDesc>
</Windows>
</Object>

My C# code:

private void button1_Click(object sender, System.EventArgs e)
{
try
{
XPathDocument xmldoc = new XPathDocument("IrisException.xml");

XPathNavigator nav = xmldoc.CreateNavigator();

XPathNodeIterator iterator;

try
{
iterator = nav.Select("//EID[. ='1']//parent::node()/EDesc");
}
catch(XPathException XPathExp)
{
Debug.WriteLine(XPathExp.Message);
return;
}

while (iterator.MoveNext())
{
Debug.WriteLine(iterator.Current.Value);
}
}
catch(Exception OtherExp)
{
Debug.WriteLine(OtherExp.Message);
}
}

I really don't want to use iterator. In the xml file, there is not extra occurence of a keyword.

Example,

1,2, 3,, 4, 5 - no occurence of same EID

1, 1, 3, 2, 2 - won't exist this in the xml file

How am i suppose to query using xpath 1 record only?

Please help! Thanks.
 
G

Guest

Hi again,

I manage to do that with XmlDocument. But i would prefer using XPathDocument. Any helps?

This code below is working:

XmlDocument xmldoc = new XmlDocument();

xmldoc.Load("IrisException.xml");

XmlNode irisNode = xmldoc.SelectSingleNode("//EID[. ='1']//parent::node()/EDesc");

Debug.WriteLine(iNode.InnerText.ToString());

Any help please? Thanks.
 
M

Martin Honnen

Chua Wen Ching wrote:

I manage to do that with XmlDocument. But i would prefer using XPathDocument. Any helps?

This code below is working:

XmlDocument xmldoc = new XmlDocument();

xmldoc.Load("IrisException.xml");

XmlNode irisNode = xmldoc.SelectSingleNode("//EID[. ='1']//parent::node()/EDesc");

Debug.WriteLine(iNode.InnerText.ToString());

There is no SelectSingleNode with XPathDocument so all you can do is to
use SelectNode and then read out the value, in the case of your example
document you could use

using System;
using System.Xml;
using System.Xml.XPath;

public class Test20040710 {
public static void Main (string[] args) {
XPathDocument xpathDocument = new
XPathDocument(@"test20040710.xml", XmlSpace.Preserve);
XPathNavigator xpathNavigator = xpathDocument.CreateNavigator();
XPathExpression xpathExpression =
xpathNavigator.Compile("//*[EID = '1']/EDesc/text()");
XPathNodeIterator xpathIterator =
xpathNavigator.Select(xpathExpression);
if (xpathIterator.MoveNext()) {
Console.WriteLine("Found text: {0}.", xpathIterator.Current.Value);
}
else {
Console.WriteLine("Not found.");
}
}
}
 
G

Guest

Thanks Martin Honnen, it works great. But i had still some doubts, hope you can help me out.

1) With your method and my xmldocument way, which one is faster? Does it makes any difference to use xpathdocument over xmldocument?

2) My xml file, does not contains namespaces and schemas. If i use or don't use them, does it makes any difference?

3) Your expression:

you: //*[EID = '1']/EDesc/text()

mine: //EID[. ='1']//parent::node()/EDesc

It seems to be lots of difference. Can my expression to be used with your way?

4) What if my xml file is like this, how will the expression looks like? I am trying to get the right attribute and the right eid with the right edesc. If not, can namespaces or schemas help me to solve.

<?xml version='1.0'?>
<Object>
<Windows id="WindowsXP">
<EID>1</EID>
<EDesc>Error 1</EDesc>
</Windows>
<Windows id="Windows98">
<EID>2</EID>
<EDesc>Error 2</EDesc>
</Windows>
</Object>

Anyway thanks for the help. Really appreciate that :)
--
Regards,
Chua Wen Ching :)


Martin Honnen said:
Chua Wen Ching wrote:

I manage to do that with XmlDocument. But i would prefer using XPathDocument. Any helps?

This code below is working:

XmlDocument xmldoc = new XmlDocument();

xmldoc.Load("IrisException.xml");

XmlNode irisNode = xmldoc.SelectSingleNode("//EID[. ='1']//parent::node()/EDesc");

Debug.WriteLine(iNode.InnerText.ToString());

There is no SelectSingleNode with XPathDocument so all you can do is to
use SelectNode and then read out the value, in the case of your example
document you could use

using System;
using System.Xml;
using System.Xml.XPath;

public class Test20040710 {
public static void Main (string[] args) {
XPathDocument xpathDocument = new
XPathDocument(@"test20040710.xml", XmlSpace.Preserve);
XPathNavigator xpathNavigator = xpathDocument.CreateNavigator();
XPathExpression xpathExpression =
xpathNavigator.Compile("//*[EID = '1']/EDesc/text()");
XPathNodeIterator xpathIterator =
xpathNavigator.Select(xpathExpression);
if (xpathIterator.MoveNext()) {
Console.WriteLine("Found text: {0}.", xpathIterator.Current.Value);
}
else {
Console.WriteLine("Not found.");
}
}
}
 
M

Martin Honnen

Chua Wen Ching wrote:

1) With your method and my xmldocument way, which one is faster? Does
it makes any difference to use xpathdocument over xmldocument?

XPathDocument is faster as it is a readonly document tuned to allow
searches while XmlDocument is slower while allowing you not only to
search for nodes but also to change them.
2) My xml file, does not contains namespaces and schemas. If i use or
don't use them, does it makes any difference?

Namespaces are possible, here is an example taken directly from the SDK
docs:

XPathDocument doc = new XPathDocument("booksort.xml");
XPathNavigator nav = doc.CreateNavigator();

//Select all ISBN attributes.
XPathExpression expr;
expr = nav.Compile("/bookstore/book/@bk:ISBN");

XmlNamespaceManager nsmgr = new XmlNamespaceManager(nav.NameTable);
nsmgr.AddNamespace("bk", "urn:samples");
expr.SetContext(nsmgr);

//Display the selection.
XPathNodeIterator iterator = nav.Select(expr);
while (iterator.MoveNext()){
Console.WriteLine(iterator.Current.ToString());
}

Schema doesn't really relate to XPath, of course you can validate your
XML against a schema before you load it into an XPathDocument.
3) Your expression:

you: //*[EID = '1']/EDesc/text()

mine: //EID[. ='1']//parent::node()/EDesc

It seems to be lots of difference. Can my expression to be used with
your way?

I had a look at your document and it seemed to me you wanted to read out
the text inside of a <EDesc> element, that is why I have appended text()
to the XPath expression. That is necessary if you want to read out the
Value property directly. The restructuring is just a matter of taste
meaning you could use
//EID[. ='1']//parent::node()/EDesc/text()
as well.
4) What if my xml file is like this, how will the expression looks
like? I am trying to get the right attribute and the right eid with
the right edesc. If not, can namespaces or schemas help me to solve.
<?xml version='1.0'?>
<Object>
<Windows id="WindowsXP">
<EID>1</EID>
<EDesc>Error 1</EDesc>
</Windows>
<Windows id="Windows98">
<EID>2</EID>
<EDesc>Error 2</EDesc>
</Windows>
</Object>

You do not need namespaces or schemas to search any XML document with
XPath, how the XPath expression has to look depends on what you want to
look for, guessing from your previous example you still want
//EID[. ='1']//parent::node()/EDesc/text()
If you want to use XPath and are not feeling strong enough then maybe
look into some tutorials, for instance
http://www.w3schools.com/xpath/default.asp
 
D

Desi Cortez

Martin said:
Chua Wen Ching wrote:



XPathDocument is faster as it is a readonly document tuned to allow
searches while XmlDocument is slower while allowing you not only to
search for nodes but also to change them.

There is also XmlReader
 
G

Guest

Thanks Martin Honnen for the great explanation.

Thanks Desi, but i am looking forward on XPath, so next time when xquery is official out, i can migrate it easier.. query query query :)

Thanks again.
 
J

Jermaine Franklin

Chua said:
Thanks Martin Honnen for the great explanation.

Thanks Desi, but i am looking forward on XPath, so next time when xquery
is official out, i can migrate it easier.. query query query :)

Thanks again.

Yes, I hear you.

Thanks for mentioning XQuery -- I had not heard of it before your posts and
last night started reading up on it.

I am not sure how XQuery integrates with c# since it seems to imply that it
is its own parser. I guess there will be some built in XQuery assembly
in .NET.

Here is some sample chapters from a cool book I found on Amazon about XQuery
-- the best part is where it contrasts XML versus RDBMS:

http://www.amazon.com/gp/reader/032...853-8522547?_encoding=UTF8&p=S001#reader-link
 
G

Guest

Hi Jermaine Franklin,

Thanks for the url.

I am thinking of writing the whole new xquery library by myself once i got approval from my boss to contrinue developing
with xquery. But first let me read more about xpath, xml schemas.. haha!

Cheers.
 

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