0

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>
4

2 に答える 2

1

したがって、問題は、再帰するたびに、新しく作成されたアイテムに要素を追加していることです。ループの方がうまくいくようです。

基本的に、コードはこれを行っています:

kml outbodyの最初の呼び出しを設定し、要素(要素1)をkmlouterboyに追加します。2番目の呼び出しは要素(要素2)を(要素1)に追加します。3番目の呼び出しは要素(要素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;
    }
}
于 2012-10-12T15:17:03.877 に答える
0

DocumentではなくPlacemarkの子として再帰的にビルドする要素を追加しています。これでうまくいくはずです:

    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;
    }
于 2012-10-12T15:18:58.813 に答える