【问题标题】:generating KML file using C# and LINQ with a recursive function使用带有递归函数的 C# 和 LINQ 生成 KML 文件
【发布时间】:2012-10-12 15:10:11
【问题描述】:

我正在尝试在 C# 中动态创建 KML 文件。我写了一个递归函数来做到这一点。但是输出的结果有点问题。问题是所有地标的结束标记的位置。我真的很困惑。请告诉我递归函数哪里出错???

我的代码:

private void xmlBuild()
    {
XDocument doc = new XDocument(
        new XDeclaration("1.0", "utf-8", ""),
        new XComment("This is comment by me"),
        new XElement(ns+"kml", 
        new XElement(ns+"Document", rec_build())));      
        doc.Save(Server.MapPath(@"~\App_Data\markers2.xml"));
}
private XElement rec_build()
    {
        if (iteration != 0)
        {
            iteration -= 1;
            return final_rec = new XElement(ns + "Placemark",
                    new XAttribute("id", "1"),
                    new XElement(ns + "title", "something"),
                    new XElement(ns + "description", "something"),
                    new XElement(ns + "LookAt",
                    new XElement(ns + "Longitude", "49.69"),
                    new XElement(ns + "Latitude", "32.345")), new XElement(ns + "Point", new XElement(ns + "coordinates", "49.69,32.345,0")),rec_build());
        }
        else
        {
            return null;
        }
    }

这是迭代值为 2 的输出:(请注意文件末尾的地标 id=1 的结束标记。它应该在地标 id=2 的开始标记之前!

<?xml version="1.0" encoding="utf-8"?>
<!--This is comment by me-->
<kml xmlns="http://earth.google.com/kml/2.2">
  <Document>
    <Placemark id="1">
      <title>something</title>
      <description>something</description>
      <LookAt>
        <Longitude>49.69</Longitude>
        <Latitude>32.345</Latitude>
      </LookAt>
      <Point>
        <coordinates>49.69,32.345,0</coordinates>
      </Point>
      <Placemark id="1">
        <title>something</title>
        <description>something</description>
        <LookAt>
          <Longitude>49.69</Longitude>
          <Latitude>32.345</Latitude>
        </LookAt>
        <Point>
          <coordinates>49.69,32.345,0</coordinates>
        </Point>
      </Placemark>
    </Placemark>
  </Document>
</kml>

【问题讨论】:

    标签: c# xml kml


    【解决方案1】:

    所以问题是每次递归时,您都在将元素添加到新创建的项目中。似乎循环会更好。

    基本上代码是这样做的:

    设置 kml outbody 第一次调用并将元素(元素 1)添加到 kml outerboy 第二次调用将元素(元素2)添加到(元素1) 第三次调用将元素(元素 3)添加到(元素 2)。

    如果您想使用递归方法而不是循环机制,请传入对外部 kml 的引用。

    如果这正是它的工作原理,那么递归会更加混乱

    (对不起,如果我有多余或缺少的括号、逗号或其他项目。我没有安装 VS)

    循环:

    private void xmlBuild()
    {
        XElement documentElement = new XElement(ns + "Document");
    
        for (int i = 0; i < 2; i++)
        {
            documentElement.Add(rec_build());
        }
    
        XDocument doc = new XDocument(
            new XDeclaration("1.0", "utf-8", ""),
            new XComment("This is comment by me"),
            new XElement(ns + "kml", documentElement));
    
        doc.Save(Server.MapPath(@"~\App_Data\markers2.xml"));
    }
    
    private XElement rec_build()
    {
    
        return new XElement(ns + "Placemark",
               new XAttribute("id", "1"),
               new XElement(ns + "title", "something"),
               new XElement(ns + "description", "something"),
               new XElement(ns + "LookAt",
               new XElement(ns + "Longitude", "49.69"),
               new XElement(ns + "Latitude", "32.345")), 
               new XElement(ns + "Point", 
               new XElement(ns + "coordinates", "49.69,32.345,0")));
    }
    

    递归:

    private void xmlBuild()
    {
        XElement docElement = new XElement(ns+"Document");
        rec_build(docElement);
        XDocument doc = new XDocument(
        new XDeclaration("1.0", "utf-8", ""),
        new XComment("This is comment by me"),
        new XElement(ns+"kml", docElement)));      
        doc.Save(Server.MapPath(@"~\App_Data\markers2.xml"));
    }
    private XElement rec_build(XElement doc)
    {
        if (iteration != 0)
        {
            iteration -= 1;
            doc.Add(new XElement(ns + "Placemark",
                    new XAttribute("id", "1"),
                    new XElement(ns + "title", "something"),
                    new XElement(ns + "description", "something"),
                    new XElement(ns + "LookAt",
                    new XElement(ns + "Longitude", "49.69"),
                    new XElement(ns + "Latitude", "32.345")), 
                    new XElement(ns + "Point", new XElement(ns + "coordinates", "49.69,32.345,0")));
            return recBuild(doc);
        }
        else
        {
            return null;
        }
    }
    

    【讨论】:

    • 我第一次尝试用 FOR 循环来做这件事,但比较困惑,所以我想出了使用递归的想法。你对使用循环有什么建议?
    • 我采纳了你的建议(调用 rec_function 外部 kml),但没有得到好的结果。你还有什么建议?
    • @AminM 更新了我的回复。它应该工作。我只是通过我的头脑(没有想法)。
    • 循环版本有问题,但递归功能完美!谢谢!并且是这个递归函数的顶级!
    【解决方案2】:

    您将递归构建元素添加为 Placemark 的子元素,而不是 Document。这应该可以解决问题:

        private void xmlBuild()
        {
            XElement docElement = new XElement(ns + "Document");
            XDocument doc = new XDocument(
                    new XDeclaration("1.0", "utf-8", ""),
                    new XComment("This is comment by me"),
                    new XElement(ns + "kml", docElement));
            rec_build(docElement);
            doc.Save(Server.MapPath(@"~\App_Data\markers2.xml"));
        }
    
        private XElement rec_build(XElement docElement)
        {
            if (iteration != 0)
            {
                iteration -= 1;
                return final_rec = new XElement(ns + "Placemark",
                        new XAttribute("id", "1"),
                        new XElement(ns + "title", "something"),
                        new XElement(ns + "description", "something"),
                        new XElement(ns + "LookAt",
                        new XElement(ns + "Longitude", "49.69"),
                        new XElement(ns + "Latitude", "32.345")), 
                        new XElement(ns + "Point", new XElement(ns + "coordinates", "49.69,32.345,0")));
                docElement.Add(final_rec);
                rec_build(docElement);
            }
            else
                return null;
        }
    

    【讨论】:

    • 我试过你的代码,这是我得到的输出:earth.google.com/kml/2.2">
    • 我在 docElement.Add(final_rec); 中有一个小错字。调用,尚未运行此代码,但在修复错字时它应该可以工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 2015-05-14
    • 1970-01-01
    • 2011-06-16
    • 2017-07-23
    相关资源
    最近更新 更多