我知道用适当的课程编写Xml文档会更好,但我的时间很短,想要快速的结果。
我尝试将xml文件写入字符串,然后将其另存为xml文件。 结果不正确,因为字符串每次只获取foreach循环的最后一个值。
我搜索了这个问题,发现我需要在foreach循环中启动字符串,但我不理解这个概念,并且不知道究竟在哪里。
我应该在代码中修改什么?
string siteMap = "<? xml version = \"1.0\" encoding = \"UTF-8\" ?>";
List<string> Niveau1Titles = getNiveau1Titles(aux1);
List<List<Couple>> Niveau2Titles = getNiveau2Titles(aux1);
int i = 0;
foreach (var n2 in Niveau2Titles)
{
siteMap += "<Niveau_1 Title = \"" + Niveau1Titles[i] + "\" >";
foreach (var n22 in n2)
{
siteMap += "<Niveau_2 Title = \"" + n22.Title + "\" Link = \"" + n22.Link + "\" >";
List<Couple> Niveau3Titles = new List<Couple>();
Niveau3Titles = getNiveau3Titles(n22.Link);
foreach(var n3 in Niveau3Titles)
{
siteMap += "<Niveau_3 Title = \"" + n3.Title + "\" Link = \"" + n3.Link + "\" />";
}
siteMap += "</Niveau_2>";
}
siteMap += "</Niveau_1>";
i++;
}
Console.WriteLine(siteMap);
答案 0 :(得分:2)
投入5分钟以确保使用LINQ to XML生成这一点似乎并不太难:
var result =
new XDocument(
new XDeclaration("1.0", "UTF-8", "yes"),
new XElement(
"sitemap",
Niveau2Titles.Zip(Niveau1Titles, (n2, n1) =>
new XElement(
"Niveau_1",
new XAttribute("Title", n1),
n2.Select(n22 =>
new XElement(
"Niveau_2",
new XAttribute("Title", n22.Title),
new XAttribute("Link", n22.Link),
getNiveau3Titles(n22.Link).Select(n3 =>
new XElement(
"Niveau_3",
new XAttribute("Title", n3.Title),
new XAttribute("Link", n3.Link)))))))));
答案 1 :(得分:0)
我认为代码工作正常。您的xml中有多个根元素。您需要添加一个根。此外,xml标识行中还有一个额外的空间。请尝试下面的代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string aux1 = "";
//remove extra space
string siteMap = "<?xml version = \"1.0\" encoding = \"UTF-8\" ?>";
siteMap += "<Root>";
List<string> Niveau1Titles = getNiveau1Titles(aux1);
List<List<Couple>> Niveau2Titles = getNiveau2Titles(aux1);
int i = 0;
foreach (var n2 in Niveau2Titles)
{
siteMap += "<Niveau_1 Title = \"" + Niveau1Titles[i] + "\" >";
foreach (var n22 in n2)
{
siteMap += "<Niveau_2 Title = \"" + n22.Title + "\" Link = \"" + n22.Link + "\" >";
List<Couple> Niveau3Titles = new List<Couple>();
Niveau3Titles = getNiveau3Titles(n22.Link);
foreach (var n3 in Niveau3Titles)
{
siteMap += "<Niveau_3 Title = \"" + n3.Title + "\" Link = \"" + n3.Link + "\" />";
}
siteMap += "</Niveau_2>";
}
siteMap += "</Niveau_1>";
i++;
}
siteMap += "</Root>";
Console.WriteLine(siteMap);
Console.ReadLine();
}
static List<string> getNiveau1Titles(string aux1)
{
return new List<string> { "aaa", "aab", "aac", "aad" };
}
static List<List<Couple>> getNiveau2Titles(string aux1)
{
return new List<List<Couple>>() {
new List<Couple>() {new Couple() { Title = "T11", Link = "L11"}, new Couple() { Title = "T12", Link = "L12"}, new Couple() { Title = "T13", Link = "L13"} },
new List<Couple>() {new Couple() { Title = "T21", Link = "L21"}, new Couple() { Title = "T22", Link = "L22"}, new Couple() { Title = "T23", Link = "L23"} },
new List<Couple>() {new Couple() { Title = "T31", Link = "L31"}, new Couple() { Title = "T32", Link = "L32"}, new Couple() { Title = "T33", Link = "L33"} },
new List<Couple>() {new Couple() { Title = "T41", Link = "L41"}, new Couple() { Title = "T42", Link = "L42"}, new Couple() { Title = "T43", Link = "L43"} }
};
}
static List<Couple> getNiveau3Titles(string aux1)
{
return new List<Couple>() { new Couple() { Title = "T100", Link = "L100" }, new Couple() { Title = "T101", Link = "L101" }, new Couple() { Title = "T102", Link = "L102" } };
}
}
public class Couple
{
public string Title { get; set; }
public string Link { get; set; }
}
}
这是xml结果
<?xml version = "1.0" encoding = "UTF-8" ?>
<Root>
<Niveau_1 Title = "aaa" >
<Niveau_2 Title = "T11" Link = "L11" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
<Niveau_2 Title = "T12" Link = "L12" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
<Niveau_2 Title = "T13" Link = "L13" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
</Niveau_1>
<Niveau_1 Title = "aab" >
<Niveau_2 Title = "T21" Link = "L21" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
<Niveau_2 Title = "T22" Link = "L22" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
<Niveau_2 Title = "T23" Link = "L23" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
</Niveau_1>
<Niveau_1 Title = "aac" >
<Niveau_2 Title = "T31" Link = "L31" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
<Niveau_2 Title = "T32" Link = "L32" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
<Niveau_2 Title = "T33" Link = "L33" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
</Niveau_1>
<Niveau_1 Title = "aad" >
<Niveau_2 Title = "T41" Link = "L41" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
<Niveau_2 Title = "T42" Link = "L42" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
<Niveau_2 Title = "T43" Link = "L43" >
<Niveau_3 Title = "T100" Link = "L100" />
<Niveau_3 Title = "T101" Link = "L101" />
<Niveau_3 Title = "T102" Link = "L102" />
</Niveau_2>
</Niveau_1>
</Root>
答案 2 :(得分:0)
在C#中使用lambda表达式或匿名方法时,我们必须警惕访问修改后的闭包陷阱。例如:
foreach (var s in strings)
{
query = query.Where(i => i.Prop == s); // access to modified closure
...
}
由于修改后的闭包,上面的代码会导致查询中的所有Where
子句都基于s
的最终值。
正如here所解释的那样,这是因为上面s
循环中声明的foreach
变量在编译器中被翻译成这样:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
而不是像这样:
while (enumerator.MoveNext())
{
string s;
s = enumerator.Current;
...
}
正如here所指出的那样,在循环外声明变量没有性能优势,在正常情况下我能想到的唯一原因就是你打算在范围之外使用变量循环:
string s;
while (enumerator.MoveNext())
{
s = enumerator.Current;
...
}
var finalString = s;
但是foreach
循环中定义的变量不能在循环外使用:
foreach(string s in strings)
{
}
var finalString = s; // won't work: you're outside the scope.
因此,编译器以一种方式声明变量,使其非常容易出现通常难以查找和调试的错误,同时不会产生可感知的好处。