LINQ to Dictionary - 使用XML

Pho*_*rce 4 c# xml linq

我已经问了一个类似的问题,但是,这个问题是不同的,我试过了.

我试图使用Linq读取XML数据,然后我解决了这个问题,但是,我需要选择多个值并将它们存储到Dictionary中.我试过了(评论是我的尝试),但我无法弄明白并得到如下错误:

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

我们假设我的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>
Run Code Online (Sandbox Code Playgroud)

现在我需要得到的是"名称"和"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")
            });
        */
Run Code Online (Sandbox Code Playgroud)

注意:我已经做了三次尝试,但是,得到相同/类似的错误消息.

Dan*_*rth 5

name并且id元素,而不是属性.因此,您需要使用Element()而不是Attribute():

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

如果name或是id可选标记,您可以使用以下代码来避免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);
Run Code Online (Sandbox Code Playgroud)

请注意:这只是忽略Placemark没有name标签的标签.仍然会考虑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>
Run Code Online (Sandbox Code Playgroud)