Подтвердить что ты не робот

Анализ XML-элементов XDocument или XElement, содержащих пространства имен

Я пытаюсь прочитать следующую строку, взятую из лог4net 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>

При попытке XElement.Parse или XDocument.Parse содержимого оно выдает исключение:

'log4net' - необъявленное пространство имен. Строка 1, позиция 2.

Я знаю, что могу искать и заменять "log4net:" в исходной строке и удалять ее, позволяя мне разбирать XML успешно, но есть ли лучший способ? Это полные данные (переформатированные для чтения), не существует никаких объявлений пространства имен xml.

4b9b3361

Ответ 1

Сначала создайте экземпляр класса XmlNamespaceManager и добавьте к нему свои пространства имен, например

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

Чтобы проанализировать XML-строку с использованием этих сопоставлений пространств имен, вызовите следующую функцию, передав экземпляр XmlNamespaceManager с пространствами имен, которые вы добавили к нему:

/// <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 );
}

Ответ 2

У вас действительно есть только два варианта:

  • Разделите "log4net:" из XML, как вы предложили;
  • Измените XML, чтобы объявить пространство имен, возможно, наиболее легко выполнить, обернув фрагмент (через StringBuilder) в корневом элементе с объявлением.

Строго говоря, ваш пример - искаженный XML - неудивительно, что XDocument/XElement не будет анализировать его.

Ответ 3

вы можете использовать что-то вроде этого:

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