【问题标题】:LINQ to Dictionary - Using XMLLINQ to Dictionary - 使用 XML
【发布时间】:2013-01-24 13:43:28
【问题描述】:

我已经问了一个类似的问题,当然,但是,这个问题不同,我已经尝试过了。

我尝试使用 Linq 读取 XML 数据并解决了这个问题,但是,我需要选择多个值并将它们存储到字典中。我已经尝试过(并且 cmets 是我的尝试),但我无法弄清楚并收到如下错误:

System.NullReferenceException:对象引用未设置为对象的实例 在 /Users/p/Projects/dsdsdsds/dsdsdsds/Main.cs:23 中的 dsdsdsds.MainClass+c__AnonStorey0.m__0 (System.Xml.Linq.XElement datanum) [0x00000]

假设我的 XML 文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
   <kml xmlns="http://www.opengis.net/kml/2.2">
     <Document>
       <name>My word place</name>
         <Placemark>
           <name>Main Building</name> 
             <id>1</id>
               <Polygon>
            <extrude>1</extrude>
         <altitudeMode>relativeToGround</altitudeMode>
       <outerBoundaryIs>
    <LinearRing>
 <coordinates>

现在我需要得到的是“名称”和“id”,并将这些值放入字典中。

这是我的代码:

var xdoc = XDocument.Load ("buildings.kml");
        XNamespace kml = "http://www.opengis.net/kml/2.2";

        var dict = xdoc.Descendants(kml + "Placemark").ToDictionary (

            datanum => datanum.Attribute(kml + "name").Value,
            datanum => datanum.Attribute(kml + "id").Value );

            /*.ToDictionary(e => e.Element("name").Value,
                                 e => e.Descendants("id")
                                    .Select (item => new Building
                                    {
                                        BuildingName = (string) e.Element(kml + "name").Value,
                                        BuildingID = Convert.ToInt16(item.Element(kml + "id").Value)
                                    }).ToList()
                                    );
        /*

        /*var buildings = xdoc.Descendants (kml + "Placemark")
            .Select((element, index) => new Building {
                BuildingName = (string) element.Element(kml + "name"),
                BuildingID = (int) element.Element(kml + "id")
            });
        */

注意:我已经进行了 3 次尝试,但是得到了相同/相似的错误消息。

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    nameid元素,而不是属性。因此,您需要使用Element() 而不是Attribute()

    var dict = xdoc.Descendants(kml + "Placemark")
                   .ToDictionary(datanum => datanum.Element(kml + "name").Value,
                                 datanum => datanum.Element(kml + "id").Value);
    

    如果nameid 是可选标签,您可以使用以下代码来避免NullReferenceException

    var dict = doc.Descendants(kml + "Placemark")
                  .Select(x => new { name = (string)x.Element(kml + "name"),
                                     id = (string)x.Element(kml + "id") })
                  .Where(x => x.name != null)
                  .ToDictionary(x => x.name, x => x.id);
    

    请注意:这只会忽略没有name 标签的Placemark 标签。 Placemark 仅带有name 标签和没有id 标签的标签仍会被考虑在内。

    顺便说一句:您的格式很好地掩盖了这一点,但是您在问题中提供的 XML 无效。正确格式化,这变得很明显:

    <?xml version="1.0" encoding="UTF-8"?>
    <kml xmlns="http://www.opengis.net/kml/2.2">
      <Document>
      <name>My word place</name>
      <Placemark>
        <name>Main Building</name> 
        <id>1</id>
        <Polygon>
          <extrude>1</extrude>
          <altitudeMode>relativeToGround</altitudeMode>
          <outerBoundaryIs>
            <LinearRing>
              <coordinates>
    

    【讨论】:

    • 感谢您的回复。我尝试了您发布的代码,但是,我得到了同样的错误:“System.NullReferenceException:对象引用未设置为 dsdsdsds.MainClass+
      c__AnonStorey0.m__1 (System.Xml.Linq. XElement datanum) [0x00000] in /Users/ph/Projects/dsdsdsds/dsdsdsds/Main.cs:19"
    • @Phorce:这意味着有Placemark 没有idname 标签。允许吗?
    • 没有。 XML 中有“id”和“name”标签(我认为这就是你的意思)每个存在“Placemark”的实例
    • @Phorce:如果是这样的话,这个异常就不会发生。至少在我给你的代码中没有。请上传完整的文件,以便我向您展示违规标签。无论如何,我用支持可能缺少标签的 XML 的版本更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多