2009-08-02 15 views
12

Próbuję odczytać następujący ciąg, przechwycony z UdPAppender log4net.XDokument lub XElement parsowanie elementu XML zawierającego przestrzenie nazw

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

Podczas próby XElement.Parse lub XDocument.Parse treść, zgłasza wyjątek:

'log4net' jest nazw nierejestrowana. Linia 1, pozycja 2.

wiem, że mogę wyszukać i zastąpić „log4net:” w oryginalnym ciąg i usunąć go, pozwalając mi do analizowania XML z powodzeniem, ale tam jest lepszy sposób? Jest to kompletne dane przechwycone (sformatowany, aby umożliwić odczyt), nie istnieją żadne deklaracje przestrzeni nazw xml wykonane lub usunięte ..

Odpowiedz

18

Najpierw utwórz instancję klasy XmlNamespaceManager i dodaj do niej swoje przestrzenie nazw.

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

do analizowania ciąg XML przy użyciu tych odwzorowań przestrzeni nazw, należy wywołać następującą funkcję, przekazując instancję XmlNamespaceManager z nazw dodanych do niego:

/// <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 za używanie 'new XmlTextReader()', przestarzałe od .NET 2.0. –

+1

@JohnSaunders, gdzie to widziałeś? Nie wygląda to na przestarzałe: http://msdn.microsoft.com/en-us/library/system.xml.xmltextreader(vsv1.110).aspx – georgiosd

+0

FYI, nie powinieneś używać 'new XmlTextReader()' lub 'nowy XmlTextWriter()'. Zostały one wycofane od .NET 2.0. Zamiast tego użyj 'XmlReader.Create()' lub 'XmlWriter.Create()'. –

11

Naprawdę masz tylko dwie opcje:

  1. Strip „log4net:” z XML, jak zasugerowałeś;
  2. Zmodyfikuj kod XML, aby zadeklarować obszar nazw, najprawdopodobniej najprościej wykonując pakowanie fragmentu (za pomocą StringBuilder) w głównym elemencie, który ma deklarację.

Ściśle mówiąc, Twój przykład jest źle sformułowany XML - nie jest to niespodzianką XDocument/XElement nie będzie analizować.

-1

można użyć coś takiego :

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