0

I do have the following xml file

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<open>1</open>
<Placemark>
    <name>L14A</name>
    <description>ID:01F40BF0
PLACEMENT:Home Woods
RSSI:-82
    </description>
        <Style>
            <IconStyle>
                <Icon>
                    <href>http://chart.apis.google.com/chart?chst=d_map_pin_letter&amp;chld=3|0000CC|FFFFFF</href>
                </Icon>
            </IconStyle>
        </Style>
        <Point>
            <coordinates>-73.16551208,44.71051217,0</coordinates>
        </Point>
    </Placemark>
</Document>
</kml>

The file is bigger than that but it does represent the structure. I'm trying to remove the element <Style> but I can't find a way to get it right.

I have tried the following method: How to remove an element from an xml using Xdocument when we have multiple elements with same name but different attributes

The code is:

    XDocument xdoc = XDocument.Load("kkk.kml");
    xdoc.Descendants("Style").Remove();
    xdoc.Save("kkk-mod.kml");

The Descendants collection is always empty.

Also, when I save the file, it does append "kml:" to each of my elements (see below).

<kml:Placemark>
    <kml:name>L14A</kml:name>
    <kml:description>ID:01F40BF0
    </kml:description>
    <kml:Point>
        <kml:coordinates>-73.200,44.500,0</kml:coordinates>
    </kml:Point>
</kml:Placemark>

How may I get it right?

  1. the remove
  2. the :kml appended in the final file.
Community
  • 1
  • 1
  • 1
    You need to include the namespace with the element name, otherwise the XML parser will not find the specified node(s). In this case, you need to use `http://www.opengis.net/kml/2.2`. – Tim Dec 04 '15 at 17:17

2 Answers2

1

You need to include the namespace in order to access the node. Based on the sampel XML you posted, the namespace is http://www.opengis.net/kml/2.2, so something like this should get you going:

XDocument xdoc = XDocument.Load("kkk.kml");
XNamespace ns = "http://www.opengis.net/kml/2.2";
xdoc.Descendants(ns + "Style").Remove();
xdoc.Save("kkk-mod.kml");

If you want to remove the "kml" prefix from the modified document, you can use the following code snippet. This will remove all the namespaces from the document.

XDocument xdoc = XDocument.Load("kkk.kml");
XNamespace ns = "http://www.opengis.net/kml/2.2";
xdoc.Descendants(ns + "Style").Remove();
XElement newDoc = RemoveAllNamespaces(xdoc.Root);
xdoc.Save("kkk-mod.kml");

public static XElement RemoveAllNamespaces(XElement e)
{

    return new XElement(e.Name.LocalName,
      (from n in e.Nodes()
       select ((n is XElement) ? RemoveAllNamespaces(n as XElement) : n)),
         (e.HasAttributes) ?
           (from a in e.Attributes()
            where (!a.IsNamespaceDeclaration)
            select new XAttribute(a.Name.LocalName, a.Value)) : null);
}

Taken from this SO answer.

The resulting XML file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<kml>
  <Document>
    <open>1</open>
    <Placemark>
      <name>L14A</name>
      <description>ID:01F40BF0
PLACEMENT:Home Woods
RSSI:-82
      </description>
      <Point>
        <coordinates>-73.16551208,44.71051217,0</coordinates>
      </Point>
    </Placemark>
  </Document>
</kml>  
Community
  • 1
  • 1
Tim
  • 28,212
  • 8
  • 63
  • 76
0

Of course, you can use a native language for XML restructuring called XSLT requiring no looping. As information, XSLT is a declarative, special-purpose programming language (same type as SQL) used to re-format, style, and re-structure XML documents for various end use needs. Practically all general purpose languages maintain XSLT processors including C#, Java, Python, PHP, Perl, and VB.

Below is a solution for future readers where the XSLT script runs an identity transform to copy entire document as is and then writes an empty template to the <Style> node, thereby removing it:

XSLT script (save as .xsl or .xslt file)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
               xmlns="http://www.opengis.net/kml/2.2" 
               xmlns:gx="http://www.google.com/kml/ext/2.2"                   
               xmlns:kml="http://www.opengis.net/kml/2.2" 
               xmlns:atom="http://www.w3.org/2005/Atom">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

  <!-- Identity Transform -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- Empty Template for Style Elemeent -->
  <xsl:template match="kml:Style"/>
</xsl:transform>

C# Script (see tutorial)

using System;
using System.Xml;
using System.Xml.Xsl; 
namespace XSLTransformation
{
    class Class1
    {
        static void Main(string[] args)
        {
            XslTransform myXslTransform; 
            myXslTransform = new XslTransform();
            myXslTransform.Load("XSLTScript.xsl"); 
            myXslTransform.Transform("InputXML.xml", "OutpuXML.xml"); 

        }
    }
}
Parfait
  • 104,375
  • 17
  • 94
  • 125