首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >XML: XElement.Parse正在引发异常

XML: XElement.Parse正在引发异常
EN

Stack Overflow用户
提问于 2015-11-10 18:47:44
回答 4查看 1.7K关注 0票数 0

我有一个xml字符串列表,需要解析这些字符串并将其加载到c#类中。我得到了空引用异常,并认为它的“根”原因是xml中使用的命名空间。我对xml不是很熟悉,所以如果这个解决方案看起来很糟糕,请提供替代方案。

下面是解析代码:

代码语言:javascript
运行
复制
XNamespace ns = "http://www.example.com/schema/msc/message";
XNamespace ns2 = "http://www.example.com/schema/msc/referral";

// data is List<string>
Parallel.ForEach(data, item =>
{
   var root = XElement.Parse(item);
   var dto = new DTO
       {
         RoutingCode = (string)root.Element("Message")
               .Element(ns + "Params")
               .Element(ns + "Events")
               .Attribute("Code")
         User = new UserDTO
                    {
                     AccountName = (string)root.Element("Message")
                                  .Element("Params")
                                  .Element("Events")
                                  .Element("ref:User")
                                  .Element("Name")
                    }
       };
     list.Add(dto);
});

下面是一个示例xml元素(减小了可读性)

代码语言:javascript
运行
复制
<Message xmlns="http://www.example.com/schema/msc/message">
  <Params> 
    <Events xmlns="http://www.example.com/schema/msc/referral" Code="AC">
      <ref:User xmlns:ref="http://www.example.com/schema/msc/referral" Name="asdf"/>
    </Events>
  </Parama>
</Message>
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-11-10 22:35:27

这里有几件事。

  1. 正如Martin所指出的,您正在使用XElement.Parse。这意味着在您的示例中,rootMessage,并且不会有该名称的子元素。
  2. 您正在正确地使用名称空间来获取路由代码,但是您忽略了它们来填充UserDTO。例如,名称应该是ns + Paramsns2 + User
  3. 用户名是一个属性,而不是一个元素。

我想提出的另一个建议是,不要过早地离开这一家。使用返回IEnumerable<T>的方法,直到不必返回为止。所以更喜欢root.Elements(ns + "Params").Elements(ns + "Events").SingleOrDefault()而不是root.Element(ns + "Params").Element(ns +"Events")。这避免了空引用异常。

把这一切加在一起,我们就会得到这样的东西:

代码语言:javascript
运行
复制
XNamespace message = "http://www.example.com/schema/msc/message";
XNamespace referral = "http://www.example.com/schema/msc/referral";

var root = XElement.Parse(xml);

var dto = new
{
    RoutingCode = (string) root.Elements(message + "Params")
        .Elements(referral + "Events")
        .Attributes("Code")
        .Single(),
    User = new
    {
        AccountName = (string) root.Elements(message + "Params")
            .Elements(referral + "Events")
            .Elements(referral + "User")
            .Attributes("Name")
            .Single()
    }
};

有关工作示例,请参见这把小提琴

票数 1
EN

Stack Overflow用户

发布于 2015-11-10 19:01:51

如果使用XElement.Parse而不是XDocument.Parse,那么root元素就是Message元素,任何选择的子元素都应该从Params元素开始。

代码语言:javascript
运行
复制
     RoutingCode = (string)root.Element(ns + "Params")
           .Element(ns2 + "Events")
           .Attribute("Code")
票数 1
EN

Stack Overflow用户

发布于 2015-11-10 19:02:12

尝试使用此代码检索属性。

代码语言:javascript
运行
复制
var doc = XDocument.Parse(xml);

XNamespace ns = "http://www.example.com/schema/msc/referral";

doc.Descendants(ns + "Events")
    .Select(e => new DTO {
                            RoutingCode = (string)e.Attribute("Code"),
                            User = new UserDTO((string)e.Element(ns + "User").Attribute("Name"))
                     });
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33637284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档