Search code examples
sortingattributesc++-clixmldocument

Sort Nodes in XmlDocument by Attribute in C++, XPath, Windows Forms


I want to sort a XML-Document by attributes of an Child-Node. I am working with Windows Forms in Visual C++. I tried to use the solution proposed here on Stackoverflow. But somehow it won't work.

My unsorted XML-Doc looks like the following:

<Message-List>
  <Message sendTime="0"></Message>
  <Message sendTime="20"></Message>
  <Message sendTime="5"></Message>
</Message-List>

My sorted XML-Doc should look like this:

<Message-List>
  <Message sendTime="0"></Message>
  <Message sendTime="5"></Message>
  <Message sendTime="20"></Message>
</Message-List>

I tried following Code, but the checkme-String returned is 0205. So the sorting doesn't even work.

System::Xml::XmlDocument^ sourceXmlDoc = gcnew XmlDocument;
sourceXmlDoc->LoadXml("<Message-List><Message sendTime=\"0\"></Message><Message sendTime=\"20\"></Message><Message sendTime=\"5\"></Message></Message-List>");
System::Xml::XPath::XPathNavigator^ navigator = sourceXmlDoc->CreateNavigator();
System::Xml::XPath::XPathExpression^ selectExpression = navigator->Compile("Message-List/Message");
System::Xml::XPath::XPathExpression^ sortExpr = navigator->Compile("@sendTime");
selectExpression->AddSort(sortExpr, XmlSortOrder::Ascending, XmlCaseOrder::None, "", XmlDataType::Text);
System::Xml::XPath::XPathNodeIterator^ nodeIterator = navigator->Select(selectExpression);
String^ checkMe;
while (nodeIterator->MoveNext())
{
    if (nodeIterator->Current->MoveToFirstAttribute())
    {
        checkMe = checkMe + nodeIterator->Current->Value;
    }
}

Furthermore, I am stuck on how to proceed in the while-loop. How can I save the resorted xmlDoc as XmlDocument?


Solution

  • I might be completely wrong since .NET is not my thing, but isn't your xpath in navigator->Compile wrong and your XML data type in selectExpression->AddSort wrong

    System::Xml::XPath::XPathExpression^ selectExpression = navigator->Compile("Message-List/Message");
    
    selectExpression->AddSort(sortExpr, XmlSortOrder::Ascending, XmlCaseOrder::None, "", XmlDataType::Number);