0

I'm trying to read an XML file and find the value of a field.

I am reading from file "MyMessage.txt":

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:com.company:request.001">
    <ReqHdr>
        <AppInstanceId>AAAA</AppInstanceId>
    </ReqHdr>
    <ReqTxInf>
        <PmtId>
            <TxId>123456</TxId>
        </PmtId>
        <MsgTyp>REQUEST</MsgTyp>
    </ReqTxInf>
</Document>

Here is the code:

// Read XElement from file
element = XElement.Parse(System.IO.File.ReadAllText(
    System.IO.Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
        "MyMessage.txt")));
try
{
    Console.WriteLine(element);
    Console.WriteLine("TxId is:" + element.Descendants("TxId").First().Value);
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
    Console.WriteLine(e.StackTrace);
}

The file is read correctly and written to the console, but the search for TxId fails.

I tried to repeat this this time creating the file in code, and the same code finds TxId:

// Create XEleemnt in code
XNamespace ns = "urn:com.company:request.001";
XElement element = new XElement(ns + "Document",
    new XElement("ReqHdr", 
        new XElement("AppInstanceId", "AAAA")),
    new XElement("ReqTxInf",
        new XElement("PmtId", 
            new XElement("TxId", "123456")),
        new XElement("MsgTyp", "request")));

try
{
    Console.WriteLine(element);
    Console.WriteLine();
    Console.WriteLine("TxId is:" + element.Descendants("TxId").First().Value);
    Console.WriteLine();
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
    Console.WriteLine(e.StackTrace);
}

Resolution
The line to read the field changed to include the name space

Console.WriteLine("TxId is:" + element.Descendants(element.Name.Namespace + "TxId").First().Value);
Yoav
  • 143
  • 2
  • 9

1 Answers1

2

You're looking for an element called TxId in no namespace - but your element is implicitly in the "urn:com.company:request.001" namespace, which is inherited from its ancestor.

So you need:

element.Descendants(ns + "TxId").First()
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thank you. How come this was not required in the example where element was built in code. I suppose when reading a string into XElement it ignores the namespace in the file? – Yoav Nov 24 '16 at 15:58
  • 1
    The example you built in code wouldn't generate the same XML. Look *very carefully* at the output of your first line - you'll see it's got `xmlns=""` in the `ReqHdr` and `ReqTxInf` elements, because nothing except the `Document` element is in the namespace. – Jon Skeet Nov 24 '16 at 16:01