使用XDocument.Save格式化kml文件的问题

时间:2018-02-01 07:56:53

标签: c# xml kml

我有一个“t.kml”文件,如下所示:

<?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>
    <name>Test.kml</name>
    <Folder>
        <name>Test</name>
        <open>1</open>
        <Placemark>
            <name>Placemark 1</name>
            <LookAt>
                <longitude>-150.7482419621821</longitude>
                <latitude>72.7616508182995</latitude>
                <altitude>0</altitude>
                <heading>-13.26929942603143</heading>
                <tilt>0</tilt>
                <range>33665.16192218825</range>
                <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
            </LookAt>
            <styleUrl>#m_ylw-pushpin</styleUrl>
            <Point>
                <gx:drawOrder>1</gx:drawOrder>
                <coordinates>-110.7484519621821,52.7616508182995,0</coordinates>
            </Point>
        </Placemark>
    </Folder>
</Document>
</kml>

当我在firefox中运行它时,它显示如下: enter image description here

我有这个简单的c#代码,它只是打开并保存它(虽然它做了很多其他事情)。

    DialogResult result = openFileDialog2.ShowDialog();

    if (result == DialogResult.OK)
    {
        string fileName = openFileDialog2.FileName;

        var xdoc = XDocument.Load(fileName, LoadOptions.None);

        xdoc.Save("G:/Projects/t1.kml", SaveOptions.None);
    }

当我打开这个新文件时保存它后显示为: enter image description here

问题是:

(1)为什么没有以正确的格式显示?

(2)为什么在每个节点之前添加“kml:”作为前缀?如何删除/格式化它们?

如何解决这两个问题?

编辑: “正确格式”是指正确的xml格式,颜色和其他格式,如第一张图片所示。

编辑2: 如何确保在浏览器中运行时,它还会显示展开/折叠图标和颜色。

2 个答案:

答案 0 :(得分:2)

<强> 1。为什么没有以正确的格式显示?

这是因为Firefox尝试根据扩展和数据自动检测文件类型。由于您的文件不以.xml结尾而XDocument.Save向输出文件添加BOM,因此该文件不会显示为XML。

因此,您可以使用XmlTextWriter保存文件而不使用BOM(请参阅this answer)或将文件重命名为.xml,如果您只想偶尔使用Firefox查看。

<强> 2。为什么在每个节点之前添加“kml:”作为前缀?如何删除/格式化它们?

那是因为kml有一个重复的命名空间,而XDocument.Save将最后一个匹配的命名空间应用于dbc在注释中提到的每个节点。此外,这只是一个你不应该担心的美容问题。

但是,您可以通过在保存之前删除xmlns:kml命名空间声明来解决此问题:

var doc = XDocument.Load(fileName, LoadOptions.None);
foreach (var attr in doc.Root.Attributes())
    if (attr.IsNamespaceDeclaration && attr.Name.LocalName == "kml")
        attr.Remove();
doc.Save(@"G:\Projects\t1.kml", SaveOptions.None);

输出

<?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:atom="http://www.w3.org/2005/Atom">
  <Document>
    <name>Test.kml</name>
    <Folder>
      <name>Test</name>
      <open>1</open>
      <Placemark>
        <name>Placemark 1</name>
        <LookAt>
          <longitude>-150.7482419621821</longitude>
          <latitude>72.7616508182995</latitude>
          <altitude>0</altitude>
          <heading>-13.26929942603143</heading>
          <tilt>0</tilt>
          <range>33665.16192218825</range>
          <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
        </LookAt>
        <styleUrl>#m_ylw-pushpin</styleUrl>
        <Point>
          <gx:drawOrder>1</gx:drawOrder>
          <coordinates>-110.7484519621821,52.7616508182995,0</coordinates>
        </Point>
      </Placemark>
    </Folder>
  </Document>
</kml>

答案 1 :(得分:1)

你的问题的一部分(关于“kml”前缀)已经被回答了,所以我只回答另一部分(关于firefox中的显示)。它在firefox(或chrome)中不显示为xml树的原因是在使用utf-8声明保存XDocument时 - 使用带有BOM(字节顺序标记)的UTF8。 BOM是文件开头的3个特殊字节,提示文件以UTF-8编码。这些字节因为某种原因而混淆了firefox,并将文件视为纯文本。

因此,要解决此问题,您需要将文档保存为UTF-8而不使用BOM,例如:

var xdoc = XDocument.Load(fileName, LoadOptions.None);
using (var writer = new XmlTextWriter(outputFile, new UTF8Encoding(false))) {
    xdoc.Save(writer);
}