c#如果找到另一个匹配项,则删除包含子项的xml节点

时间:2018-01-29 07:44:44

标签: c# xml linq

我有一个xml文件,其中包含许多地标标记,其中包含很少的节点。如果发现任何重复,我想删除整个地标标记。如果这可能与linq?其实我对Linq不太熟悉,所以请你指导我正确的方向。

                   <?xml version="1.0" encoding="UTF-8"?>
        <kml xmlns="http://www.opengis.net/kml/2.2">
          <Document>
            <Placemark>
              <name>Entity references example</name>
              <description>
                    &lt;h1&gt;Entity references are hard to type!&lt;/h1&gt;
                    &lt;p&gt;&lt;font color="green"&gt;Text is 
                  &lt;i&gt;more readable&lt;/i&gt; 
                  and &lt;b&gt;easier to write&lt;/b&gt; 
                  when you can avoid using entity references.&lt;/font&gt;&lt;/p&gt;
              </description>
              <Point>
                <coordinates>102.594411,14.998518</coordinates>
              </Point>
            </Placemark>

        <Placemark>
              <name>Entity references example</name>
              <description>
                    &lt;h1&gt;Entity references are hard to type!&lt;/h1&gt;
                    &lt;p&gt;&lt;font color="green"&gt;Text is 
                  &lt;i&gt;more readable&lt;/i&gt; 
                  and &lt;b&gt;easier to write&lt;/b&gt; 
                  when you can avoid using entity references.&lt;/font&gt;&lt;/p&gt;
              </description>
              <Point>
                <coordinates>102.594411,14.998518</coordinates>
              </Point>
            </Placemark>

        <Placemark>
              <name>Entity references</name>
              <description>
                    &lt;h1&gt;Entity references are hard to type!&lt;/h1&gt;
                    &lt;p&gt;&lt;font color="green"&gt;Text is 
                  &lt;i&gt;more readable&lt;/i&gt; 
                  and &lt;b&gt;easier to write&lt;/b&gt; 
                  when you can avoid using entity references.&lt;/font&gt;&lt;/p&gt;
              </description>
              <Point>
                <coordinates>102.594411,14.998518</coordinates>
              </Point>
            </Placemark>

              <Placemark>
              <name>Entity references example</name>
              <description>
                    &lt;h1&gt;Entity references are hard to type!&lt;/h1&gt;
                    &lt;p&gt;&lt;font color="green"&gt;Text is 
                  &lt;i&gt;more readable&lt;/i&gt; 
                  and &lt;b&gt;easier to write&lt;/b&gt; 
                  when you can avoid using entity references.&lt;/font&gt;&lt;/p&gt;
              </description>
              <Point>
                <coordinates>112.594411,14.998518</coordinates>
              </Point>
            </Placemark>
          </Document>
        </kml>

编辑:试过这个,但它没有删除整个地标标记

var xdoc = XDocument.Load("C:/a.xml");
xdoc.Root.Elements("Document").GroupBy(i => (string)i.Element("Placemark")) .SelectMany(g => g.Skip(1)) .Remove();

地标可以包含其他元素,例如:

<Placemark>
  <name>Absolute Extruded</name>
  <description>Transparent green wall with yellow outlines</description>
  <styleUrl>#yellowLineGreenPoly</styleUrl>
  <LineString>
    <extrude>1</extrude>
    <tessellate>1</tessellate>
    <altitudeMode>absolute</altitudeMode>
    <coordinates> -112.2550785337791,36.07954952145647,2357
      -112.2549277039738,36.08117083492122,2357
      -112.2552505069063,36.08260761307279,2357
      -112.2564540158376,36.08395660588506,2357
      -112.2580238976449,36.08511401044813,2357
      -112.2595218489022,36.08584355239394,2357
      -112.2608216347552,36.08612634548589,2357
      -112.262073428656,36.08626019085147,2357
      -112.2633204928495,36.08621519860091,2357
      -112.2644963846444,36.08627897945274,2357
      -112.2656969554589,36.08649599090644,2357 
    </coordinates>
  </LineString>
</Placemark>

2 个答案:

答案 0 :(得分:1)

这将为您提供不同的地标

XNamespace ns = "http://www.opengis.net/kml/2.2";
var doc = XDocument.Load("file.xml");
var query = doc.Root
                .Element(ns + "Document")
                .Elements(ns + "Placemark")
                .Select(x => new  
                {
                    Name = x.Element(ns + "name").Value,
                    Description = x.Element(ns + "description").Value,
                })
                .GroupBy(x => new { x.Name, x.Description })
                .Select(g => g.First());

然后把它们写回一个文件(或者你想用它们做什么好事)

  

注意:如果地标不是确实,这将不起作用   相同

答案 1 :(得分:1)

以您尝试过的代码为基础,通过其字符串表示来比较元素相等性,并添加默认命名空间处理:

XNamespace ns = "http://www.opengis.net/kml/2.2";
xdoc.Root
    .Elements(ns+"Document")
    .Elements(ns+"Placemark")
    .GroupBy(i => (string)i)
    .SelectMany(g => g.Skip(1))
    .Remove();

<强> dotnetfiddle demo

  

“为什么我们必须使用XNamespace?是否必须使用它?”

请注意,您的XML在根元素处声明了default namespace,其URI是"http://www.opengis.net/kml/2.2"。根据默认命名空间的定义,根元素以及所有没有前缀的后代元素都属于此命名空间,因此使用XNamespace