ldam
ldam

Reputation: 4585

Find an element with a period in it's name

I have the following XML:

<T24.MESSAGE>
<TRANSACTION.TYPE>CHEQUE.ON.THEM.AUTH</TRANSACTION.TYPE>
<TRANSACTION.ID>FT14273PKQ14</TRANSACTION.ID>
</T24.MESSAGE>

I am trying to find the TRANSACTION.TYPE element, using the xpath query /TRANSACTION.TYPE. However, this is returning nothing, and I think it is because the element has a period in the name.

Is there a way to escape the period? Though according to the MS reference it isn't needed. http://msdn.microsoft.com/en-us/library/ms256199%28v=vs.110%29.aspx

Edit: I have also tried /T24.MESSAGE/TRANSACTION.TYPE and just TRANSACTION.TYPE and neither work.

Code I use to read it:

byte[] xmlBytes = Encoding.UTF8.GetBytes(strXML);
using (MemoryStream xmlStream = new MemoryStream(xmlBytes))
{
   XPathDocument doc = new XPathDocument(XmlReader.Create(xmlStream, xmlReaderSettings));
   var navigator = doc.CreateNavigator();
   var node = navigator.SelectSingleNode("/TRANSACTION.TYPE"); //null
   //...
}

Upvotes: 1

Views: 943

Answers (3)

petelids
petelids

Reputation: 12815

The issue is with your namespace. You'll need to create a XmlNamespaceManager and pass that to your SelectSingleNode call.

In the below I've created a namespace of urn:test:

string strXML = @"<?xml version='1.0'?>
            <T24.MESSAGE xmlns=""urn:Test"">
            <TRANSACTION.TYPE>CHEQUE.ON.THEM.AUTH</TRANSACTION.TYPE>
            <TRANSACTION.ID>FT14273PKQ14</TRANSACTION.ID>
            </T24.MESSAGE>";

byte[] xmlBytes = Encoding.UTF8.GetBytes(strXML);
using (MemoryStream xmlStream = new MemoryStream(xmlBytes))
{
    XPathDocument doc = new XPathDocument(XmlReader.Create(xmlStream));
    var navigator = doc.CreateNavigator();

    XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(navigator.NameTable);

    //Add the namespaces used. In this instance I'm setting a prefix of "t"
    xmlnsManager.AddNamespace("t", "urn:Test");

    //pass the XmlNamespaceManager to the call to SelectSingleNode
    //the XPath also includes the root element
    var node = navigator.SelectSingleNode("//t:T24.MESSAGE/t:TRANSACTION.TYPE", xmlnsManager);

    Console.WriteLine(node.Name);

}

This code correctly ouptuts

TRANSACTION.TYPE

Upvotes: 1

Hans Kilian
Hans Kilian

Reputation: 25120

Since you're using namespaces you might try using a namespace agnostic form in your code. It'd look like this

    var node = navigator.SelectSingleNode("//*[local-name()='TRANSACTION.TYPE']");

Upvotes: 1

Tony Stark
Tony Stark

Reputation: 771

This certainly works

string yourXMLString = @"<T24.MESSAGE>
                         <TRANSACTION.TYPE>CHEQUE.ON.THEM.AUTH</TRANSACTION.TYPE>
                         <TRANSACTION.ID>FT14273PKQ14</TRANSACTION.ID>
                         </T24.MESSAGE>";

XDocument xDoc = XDocument.Parse(yourXMLString);

var res = xDoc.Descendants("T24.MESSAGE")
              .Elements("TRANSACTION.TYPE");

result: <TRANSACTION.TYPE>CHEQUE.ON.THEM.AUTH</TRANSACTION.TYPE>

Upvotes: 0

Related Questions