views:

1618

answers:

3

I am try to read the following string, captured from a log4net UdpAppender.

<log4net:event logger="TestingTransmitter.Program" 
         timestamp="2009-08-02T17:50:18.928+01:00" 
         level="ERROR" 
         thread="9" 
         domain="TestingTransmitter.vshost.exe" 
         username="domain\user">
    <log4net:message>Log entry 103</log4net:message>
    <log4net:properties>
     <log4net:data name="log4net:HostName" value="machine" />
    </log4net:properties>
</log4net:event>

When trying to XElement.Parse or XDocument.Parse the content, it throws an exception:

'log4net' is an undeclared namespace. Line 1, position 2.

I know I can search and replace "log4net:" in the original string and remove it, allowing me to parse the XML successfully, but is there a better way? This is the complete data captured (reformatted to allow reading), there are no xml namespace declarations made or removed..

+4  A: 

You really only have two options:

  1. Strip "log4net:" from the XML, as you suggested;
  2. Modify the XML to declare the namespace, probably most easily accomplished by wrapping the fragment (via StringBuilder) in a root element that has the declaration.

Strictly speaking, your example is malformed XML -- it's no surprise XDocument / XElement won't parse it.

Ben M
A: 

First create new XmlNamespaceManager, and add your namespace info, e.g.

    XmlNamespaceManager mngr = new XmlNamespaceManager( new NameTable() );
    mngr.AddNamespace( "xsi", "http://www.w3.org/2001/XMLSchema-instance" );
    mngr.AddNamespace( "xsd", "http://www.w3.org/2001/XMLSchema" );

then call

/// <summary>Same as XElement.Parse(), but supports XML namespaces.</summary>
/// <param name="strXml">A System.String that contains XML.</param>
/// <param name="mngr">The System.Xml.XmlNamespaceManager to use for looking up namespace information.</param>
/// <returns>An System.Xml.Linq.XElement populated from the string that contains XML.</returns>
// The XML namespaces support in the framework feels f*****' under-engineered.
public static XElement ParseElement( string strXml, XmlNamespaceManager mngr )
{
    XmlParserContext parserContext = new XmlParserContext( null, mngr, null, XmlSpace.None );
    XmlTextReader txtReader = new XmlTextReader( strXml, XmlNodeType.Element, parserContext );
    return XElement.Load( txtReader );
}
Soonts