[英]Generate XML with attributes within the tags in c#
我有以下XML结构。
<a>
<b>
<c>
<d>54</d>
<e>US</e>
<f>Canada</f>
<g>
<h>
<i1>39</i1>
<i2>Belgium</i2>
<i3>Russia</i3>
</h>
<h>
<i1>43</i1>
<i2>Fran</i2>
<i3>Ger</i3>
</h>
</g>
</c>
<c>
<d>5</d>
<e>US</e>
<f>Can</f>
<g>
<h>
<i1>29</i1>
<i2>Brit</i2>
<i3>Ice</i3>
</h>
<h>
<i1>95</i1>
<i2>Russia</i2>
<i3>Nero</i3>
</h>
<h>
<i1>4323</i1>
<i2>Polska</i2>
<i3>503</i3>
</h>
</g>
</c>
</b>
<b2>
<c2>
<d2>551</d2>
<d3>Indo</d3>
<e2>
<f2>
<g2>Irnna</g2>
<g3>Mehak</g3>
<g4>Vodka</g4>
<h2>
<i2>
<j1>44</j1>
<j6>Germ0</j6>
</i2>
<i21>Finish</i21>
</f2>
</e2>
<f3>544</f3>
<g3>fur</g3>
<h3>denmark</h3>
<k1>lur</k1>
<k2>Bern</k2>
<k3>Zurick</k3>
<k4>Italy</k4>
</c2>
</b2>
<b3>35</b3>
<b4>ferha</b4>
<b5>english</b5>
<b6>334</b6>
</a>
我需要像下面这样转换它-
<a>
<b>
<c d="54"; e="US"; f="Canada">
<g>
<h i1="39"; i2 = "Belgium"; i3 ="Russia">
<h i1="393"; i2 = "Fran"; i3 ="Ger">
</g>
</c>
<c>
.
.
.
.
这意味着将所有属性放入标签中。 我使用了以下C#代码-
var xDoc = XDocument.Load("my.xml");
var xNode =
new XElement("a",
from name in xDoc.Root.Elements()
select new XElement(name.Name,
from names in name.Elements()
select new XElement(names.Name,
from namesElement in names.Elements()
where namesElement.Name.LocalName != "g"
select new XAttribute(namesElement.Name.LocalName, (string)namesElement),
new XElement("g",
from Parts in names.Element("g").Elements()
select new XElement(Parts.Name,
from routeElement in Parts.Elements()
select new XAttribute(routeElement.Name.LocalName, (string)routeElement))))));
但是,我遇到了错误。 您能给我任何提示或更正我的代码有什么问题吗? 实际上,它一直有效到(上半年)。 当结构在下半部分更改时,将显示错误,例如“对象引用未设置为对象的实例。”,“重复属性”。 你能告诉我我的方法是否正确吗? 逻辑结构有什么问题吗?
您的样本输入XML文档缺少h2元素的结束标记。 另外,输入XML文档中的值与预期输出XML中的值不匹配。 话虽如此,我使用了示例输入(我添加了缺少的h2关闭标记)并通过以下代码运行了它:
XDocument xDoc = XDocument.Load("my.xml");
XElement[] elements = xDoc.DescendantNodes()
.Where(n => n.NodeType == XmlNodeType.Text).Select(n => n.Parent).ToArray();
foreach (XElement element in elements)
{
element.Parent.SetAttributeValue(element.Name, element.Value);
element.Remove();
}
结果输出是这样的:
<a b3="35" b4="ferha" b5="english" b6="334">
<b>
<c d="54" e="US" f="Canada">
<g>
<h i1="39" i2="Belgium" i3="Russia" />
<h i1="43" i2="Fran" i3="Ger" />
</g>
</c>
<c d="5" e="US" f="Can">
<g>
<h i1="29" i2="Brit" i3="Ice" />
<h i1="95" i2="Russia" i3="Nero" />
<h i1="4323" i2="Polska" i3="503" />
</g>
</c>
</b>
<b2>
<c2 d2="551" d3="Indo" f3="544" g3="fur" h3="denmark" k1="lur" k2="Bern" k3="Zurick" k4="Italy">
<e2>
<f2 g2="Irnna" g3="Mehak" g4="Vodka">
<h2 i21="Finish">
<i2 j1="44" j6="Germ0" />
</h2>
</f2>
</e2>
</c2>
</b2>
</a>
这似乎是您想要的东西,但是如果没有,代码可以为您指明正确的方向。
我使用的是LINQ方法语法而不是您使用的查询语法,但是我认为那部分不重要。 但是我注意到您正在寻找特定的元素,例如“ a”或“ g”,并且我想看看是否可以用更一般的方式来完成。
在撰写本文时,我也遇到了空引用异常。 例如,我最初将elements
变量作为IEnumerable<XElement>
,但是后来我将在foreach
从其父级中删除一个元素,并且在下一次迭代中将有一些LINQ延迟执行,因此它将返回DescendantNodes()
但在删除该元素后无法正常工作,我会看到null引用异常。 因此,我不再使用LINQ更改内容,而是使用ToArray()
集合,以便所有执行立即进行,而我使用数组。 我提到所有这一切,因为也许您也正在发生这种事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.