Parse XDocument without having to keep specifying the default namespace

TeamWild picture TeamWild · Sep 12, 2011 · Viewed 7.6k times · Source

I have some XML data (similar to the sample below) and I want to read the values in code.

Why am I forced to specify the default namespace to access each element? I would have expected the default namespace to be used for all elements.

Is there a more logical way to achieve my goal?

Sample XML:

<?xml version="1.0" encoding="UTF-8"?>
<ReceiptsBatch xmlns="http://www.secretsonline.gov.uk/secrets">
    <MessageHeader>
        <MessageID>00000173</MessageID>
        <Timestamp>2009-10-28T16:50:01</Timestamp>
        <MessageCheck>BX4f+RmNCVCsT5g</MessageCheck>
    </MessageHeader>
    <Receipts>
        <Receipt>
            <Status>OK</Status>
        </Receipt>
    </Receipts>
</ReceiptsBatch>

Code to read xml elements I'm after:

XDocument xDoc = XDocument.Load( FileInPath );

XNamespace ns = "http://www.secretsonline.gov.uk/secrets";

XElement MessageCheck = xDoc.Element(ns+ "MessageHeader").Element(ns+"MessageCheck");
XElement MessageBody = xDoc.Element("Receipts");

Answer

Sam picture Sam · Aug 29, 2013

As suggested by this answer, you can do this by removing all namespaces from the in-memory copy of the document. I suppose this should only be done if you know you won't have name collisions in the resulting document.

/// <summary>
/// Makes parsing easier by removing the need to specify namespaces for every element.
/// </summary>
private static void RemoveNamespaces(XDocument document)
{
    var elements = document.Descendants();
    elements.Attributes().Where(a => a.IsNamespaceDeclaration).Remove();
    foreach (var element in elements)
    {
        element.Name = element.Name.LocalName;

        var strippedAttributes =
            from originalAttribute in element.Attributes().ToArray()
            select (object)new XAttribute(originalAttribute.Name.LocalName, originalAttribute.Value);

        //Note that this also strips the attributes' line number information
        element.ReplaceAttributes(strippedAttributes.ToArray());
    }
}