Анализ 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.
Ответы
Ответ 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>