Разбор XDocument или XElement XML-элемента, содержащего пространства имен - PullRequest
14 голосов
/ 02 августа 2009

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

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

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

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

Ответы [ 3 ]

20 голосов
/ 27 августа 2010

Сначала создайте экземпляр класса 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 );
}
11 голосов
/ 02 августа 2009

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

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

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

0 голосов
/ 22 января 2015

вы можете использовать что-то подобное:

<event xmlns="http://..." >
    <message xmlns="http://...">...</message>
</event>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...