【问题标题】:XDocument or XElement parsing of XML element containing namespaces包含命名空间的 XML 元素的 XDocument 或 XElement 解析
【发布时间】:2010-11-16 04:57:25
【问题描述】:

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

【问题讨论】:

    标签: c# linq-to-xml log4net


    【解决方案1】:

    你可以使用类似的东西:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • -1 用于使用 new XmlTextReader(),自 .NET 2.0 起已弃用。
      • @JohnSaunders 你在哪里看到的?它看起来并没有被弃用:msdn.microsoft.com/en-us/library/…
      • 仅供参考,您不应使用new XmlTextReader()new XmlTextWriter()。自 .NET 2.0 以来,它们已被弃用。请改用XmlReader.Create()XmlWriter.Create()
      • @JohnSaunders 看起来您的评论已被弃用,而 XmlTextReader 不是:-)
      • @georgiosd:“deprecated”这个词可能过于苛刻,但请参阅同页,“在 .NET Framework 2.0 版本中,推荐的做法是使用 XmlReader.Create 创建 XmlReader 实例方法。这使您可以充分利用此版本中引入的新功能。有关详细信息,请参阅创建 XML 阅读器。"
      【解决方案3】:

      你真的只有两个选择:

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

      严格来说,您的示例是格式错误的 XML——毫无疑问 XDocument / XElement 不会解析它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-01
        • 1970-01-01
        • 2014-06-04
        • 2018-12-30
        • 1970-01-01
        • 2015-09-19
        相关资源
        最近更新 更多