Sorting XML tags

S

schaf

Hi NG!
I'm reading a XML file which contains a namespace. So I create a
NameSpaceManager to use the .Select() functions on the XmlDocument and
XmlNode classes.

Reading like following example:

string sXPath = string.Format("ab:book[ab:price<='{0}']",
dPrice.ToString(System.Globalization.CultureInfo.InvariantCulture));
XmlNodeList xmlbookList = xmlDocBooks.Select(sXPath,
m_xmlNameSpaceMgr);

Now I would like to sort my values in the xmlbookList.
Do I really have to use a while statement for getting my first two
books with the lowest price?

I tried the whole thing by using XPathNavigator but it is not possible
to add the XmlNamespaceManager and so the statements does not work as
soon as I have a Namespace in the XML file.

Do you have a hint ?
Regards
 
M

Martin Honnen

schaf said:
string sXPath = string.Format("ab:book[ab:price<='{0}']",
dPrice.ToString(System.Globalization.CultureInfo.InvariantCulture));
XmlNodeList xmlbookList = xmlDocBooks.Select(sXPath,
m_xmlNameSpaceMgr);

Note that with XPath 1.0 <= works on numbers but not on strings so
usually you want string.Format("ab:book[ab:price<={0}]", ...). A string
Now I would like to sort my values in the xmlbookList.
Do I really have to use a while statement for getting my first two
books with the lowest price?

I tried the whole thing by using XPathNavigator but it is not possible
to add the XmlNamespaceManager and so the statements does not work as
soon as I have a Namespace in the XML file.

You can use an XmlNamespaceManager with an IXmlNamespaceResolver with
XPathNavigator:
<http://msdn2.microsoft.com/en-us/library/6k4x060d.aspx>

And you can pass in an XPathExpression on which you can define a sort
and a namespace manager
<http://msdn2.microsoft.com/en-us/library/system.xml.xpath.xpathexpression.addsort.aspx>
<http://msdn2.microsoft.com/en-us/library/system.xml.xpath.xpathexpression.setcontext.aspx>
So that way you set up the expression with all details first and then
pass it to the Select method of XPathNavigator.
 
S

schaf

Hi Martin!
You can use an XmlNamespaceManager with an IXmlNamespaceResolver with
XPathNavigator:
<http://msdn2.microsoft.com/en-us/library/6k4x060d.aspx>

And you can pass in an XPathExpression on which you can define a sort
and a namespace manager
<http://msdn2.microsoft.com/en-us/library/system.xml.xpath.xpathexpres...>
<http://msdn2.microsoft.com/en-us/library/system.xml.xpath.xpathexpres...>
So that way you set up the expression with all details first and then
pass it to the Select method of XPathNavigator.

Unfortunately I'm using .NET 1.1.

I have seen, that I can set the namespaceManager with SetContext:

XPathNavigator nav = xmlBooks.CreateNavigator();
XPathExpression xPathEx = nav.Compile("ab:book[ab:price>='1.73']");
xPathEx.AddSort("ab:price", XmlSortOrder.Ascending, XmlCaseOrder.None,
"", XmlDataType.Number);
xPathEx.SetContext(m_xmlNameSpaceMgr);
XPathNodeIterator iter = nav.Select(xPathEx);
Console.WriteLine(iter);

But iter does not contain some nodes. If I do not add the AddSort Line
it works fine.
What is wrong with my sort?
 
M

Martin Honnen

schaf said:
XPathNavigator nav = xmlBooks.CreateNavigator();
XPathExpression xPathEx = nav.Compile("ab:book[ab:price>='1.73']");
xPathEx.AddSort("ab:price", XmlSortOrder.Ascending, XmlCaseOrder.None,
"", XmlDataType.Number);
xPathEx.SetContext(m_xmlNameSpaceMgr);
XPathNodeIterator iter = nav.Select(xPathEx);
Console.WriteLine(iter);

But iter does not contain some nodes. If I do not add the AddSort Line
it works fine.
What is wrong with my sort?

The only thing that looks wrong to me is the Console.WriteLine(iter),
you should use MoveNext on iter to check whether any nodes are contained
in the node iterator. Otherwise I am not sure what is wrong but it is
hard to tell exactly where things could go wrong, I would need to see
the XML, what xmlBooks is to judge whether the relative XPath expression
ab:book makes sense for instance.
 
S

schaf

Hi all!
I have the solution...sorting works fine!

XPathNavigator nav = xmlBooks.CreateNavigator();
XPathExpression xPathEx = nav.Compile("ab:book[ab:price>='1.73']");
xPathEx.SetContext(m_xmlNameSpaceMgr);
XPathExpression xSort = nav.Compile("ab:price");
xSort.SetContext(m_xmlNameSpaceMgr);
xPathEx.AddSort(xSort, XmlSortOrder.Ascending, XmlCaseOrder.None, "",
XmlDataType.Number);
XPathNodeIterator iter = nav.Select(xPathEx);
while (iter.MoveNext()) {
XPathNavigator currNav = iter.Current;
Console.WriteLine(currNav);
}

Thanks
 
F

Frank Swarbrick

Hi all!
I have the solution...sorting works fine!

XPathNavigator nav = xmlBooks.CreateNavigator();
XPathExpression xPathEx = nav.Compile("ab:book[ab:price>='1.73']");
xPathEx.SetContext(m_xmlNameSpaceMgr);
XPathExpression xSort = nav.Compile("ab:price");
xSort.SetContext(m_xmlNameSpaceMgr);
xPathEx.AddSort(xSort, XmlSortOrder.Ascending, XmlCaseOrder.None, "",
XmlDataType.Number);
XPathNodeIterator iter = nav.Select(xPathEx);
while (iter.MoveNext()) {
XPathNavigator currNav = iter.Current;
Console.WriteLine(currNav);
}


Not relevant to the issue at hand, but might you also want to change the
following:

XPathNodeIterator iter = nav.Select(xPathEx);
while (iter.MoveNext()) {
XPathNavigator currNav = iter.Current;
Console.WriteLine(currNav);
}

....to something like this?

foreach (XPathNavigator currNav in nav.Select(xPathEx)) {
Console.WriteLine(currNav);
}

Not tested. See the following for more info:
http://www.topxml.com/rbnews/XmlDocument/re-7004_foreach-and-XPathNodeIterat
or---finally-together.aspx

I'm a fan of "foreach", so the original code jumped out at me.

Frank
 

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

Members online

Forum statistics

Threads
474,008
Messages
2,570,270
Members
46,873
Latest member
HeidiWeing

Latest Threads

Top