2009-08-02 10 views
12

Estoy tratando de leer la siguiente cadena, capturada de un log4net UdpAppender.Análisis XDocument o XElement del elemento XML que contiene los espacios de nombres

<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> 

Al intentar XElement.Parse o XDocument.Parse el contenido, se produce una excepción:

'log4net' es un espacio de nombres no declarado. Línea 1, posición 2.

Sé que puedo buscar y reemplazar "log4net:" en la cadena original y eliminarlo, lo que me permite analizar el código XML con éxito, pero hay una manera mejor? Estos son los datos completos capturado (reordenada para permitir la lectura), no hay declaraciones de espacios de nombres XML o desconectar ..

Respuesta

18

Primero, cree una instancia de la clase XmlNamespaceManager y agregue sus espacios de nombres a esa, p. Ej.

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"); 

para analizar una cadena XML usando esas asignaciones de espacio de nombres, llamar a la siguiente función, pasando la instancia de XmlNamespaceManager con los espacios de nombres que ha añadido a ella:

/// <summary>Same as XElement.Parse(), but supports XML namespaces.</summary> 
/// <param name="strXml">A String that contains XML.</param> 
/// <param name="mngr">The XmlNamespaceManager to use for looking up namespace information.</param> 
/// <returns>An XElement populated from the string that contains XML.</returns> 
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); 
} 
+0

-1 para usar 'new XmlTextReader()', en desuso desde .NET 2.0. –

+1

@JohnSaunders, ¿dónde viste esto? No parece obsoleto: http://msdn.microsoft.com/en-us/library/system.xml.xmltextreader(v=vs.110).aspx – georgiosd

+0

FYI, no debe usar 'new XmlTextReader()' o 'nuevo XmlTextWriter()'. Han sido desaprobados desde .NET 2.0. Use 'XmlReader.Create()' o 'XmlWriter.Create()' en su lugar. –

11

que realmente sólo tienen dos opciones:

  1. de Gaza "log4net:" del XML, como sugeriste;
  2. Modifique el XML para declarar el espacio de nombres, probablemente lo más fácilmente posible al envolver el fragmento (a través de StringBuilder) en un elemento raíz que tenga la declaración.

Estrictamente hablando, su ejemplo es XML mal formado - no sorprende que XDocument/XElement no lo analice.

-1

se puede usar algo como eso :

<event xmlns="http://..." > 
    <message xmlns="http://...">...</message> 
</event> 
Cuestiones relacionadas