包含命名空间的 XML 元素的 XDocument 或 XElement 解析

发布于 2024-07-29 07:32:00 字数 808 浏览 8 评论 0原文

我尝试读取从 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 命名空间声明。

I am try to read the following string, captured from a 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>

When trying to XElement.Parse or XDocument.Parse the content, it throws an exception:

'log4net' is an undeclared namespace.
Line 1, position 2.

I know I can search and replace "log4net:" in the original string and remove it, allowing me to parse the XML successfully, but is there a better way? This is the complete data captured (reformatted to allow reading), there are no xml namespace declarations made or removed..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

策马西风 2024-08-05 07:32:00

首先,创建 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 );
}

First, create an instance of XmlNamespaceManager class, and add your namespaces to that, e.g.

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

To parse an XML string using those namespace mappings, call the following function, passing the instance of XmlNamespaceManager with the namespaces you've added to it:

/// <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 );
}
·深蓝 2024-08-05 07:32:00

您实际上只有两个选择:

  1. 按照您的建议,从 XML 中删除“log4net:”;
  2. 修改 XML 以声明命名空间,这可能最容易通过将片段(通过 StringBuilder)包装在具有声明的根元素中来完成。

严格来说,您的示例是格式错误的 XML —— XDocument / XElement 无法解析它也就不足为奇了。

You really only have two options:

  1. Strip "log4net:" from the XML, as you suggested;
  2. Modify the XML to declare the namespace, probably most easily accomplished by wrapping the fragment (via StringBuilder) in a root element that has the declaration.

Strictly speaking, your example is malformed XML -- it's no surprise XDocument / XElement won't parse it.

岁月如刀 2024-08-05 07:32:00

你可以使用类似的东西:

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

you can use something like that:

<event xmlns="http://..." >
    <message xmlns="http://...">...</message>
</event>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文