如何在C#中将XML文件转换为CSV文件,只显示这些标签:<original-impot-no>, <price>, <Small-price>, <Big-price>
?
示例XML代码:它代表几行中的一行,每行可能包含几个<product-lineitem>
Tags
<?xml version="1.0" encoding="UTF-8"?>
<impots xmlns="http://www.google.com/xml/impot//20016-02-31">
<impot impot-no="W0110891258">
<impot-date>2017-12-10T22:33:35.000Z</impot-date>
<prop-by>Yallo</prop-by>
<original-impot-no>891258</original-impot-no>
<currency>EUR</currency>
<server-locale>Esp</server-locale>
<lax>gross</lax>
<current-impot-no>123358</current-impot-no>
<product-lineitems>
<product-lineitem>
<price>450</price>
<red>6.50</red>
<Small-price>39</Small-price>
<Big-price>3229</Big-price>
<lineitem-text>Grand create</lineitem-text>
<basis>234.00</basis>
</product-lineitem>
</product-lineitems>
<product-lineitem>
<price>432</price>
<red>12</red>
<Small-price>44</Small-price>
<Big-price>34</Big-price>
<lineitem-text>Small create</lineitem-text>
<basis>44.00</basis>
</product-lineitem>
</product-lineitems>
</impot>
</impots>
我应该在CSV文件中得到这样的内容:
891258;450;39;229
891258;432;44;34
C#代码:
我面对这个代码的问题是我无法检索TAG <impot>
的descandent
XmlTextReader xtr = new XmlTextReader(@"C:\Temp_Convert\Impot.xml");
StringBuilder dataToBeWritten = new StringBuilder();
while (xtr.Read())
{
if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "original-impot-no")
{
string s1 = xtr.ReadElementString();
dataToBeWritten.Append(s1);
dataToBeWritten.Append(";");
}
else if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "price")
{
string s2 = xtr.ReadElementString();
dataToBeWritten.Append(s2);
dataToBeWritten.Append(";");
}
else if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "Small-price")
{
string s2 = xtr.ReadElementString();
dataToBeWritten.Append(s2);
dataToBeWritten.Append(";");
dataToBeWritten.Append(0);
dataToBeWritten.Append(Environment.NewLine);
}
else if (xtr.NodeType == XmlNodeType.Element && xtr.Name == "Big-price")
{
string s2 = xtr.ReadElementString();
dataToBeWritten.Append(s2);
dataToBeWritten.Append(";");
dataToBeWritten.Append(0);
dataToBeWritten.Append(Environment.NewLine);
}
}
File.WriteAllText(@"C:\Temp_Convert\Impot.csv", dataToBeWritten.ToString());
}
有人可以提出解决方案,非常感谢你提前。
您的XML无效。我猜这里是正确的格式。
<?xml version="1.0" encoding="UTF-8"?>
<impots xmlns="http://www.google.com/xml/impot//20016-02-31">
<impot impot-no="W0110891258">
<impot-date>2017-12-10T22:33:35.000Z</impot-date>
<prop-by>Yallo</prop-by>
<original-impot-no>891258</original-impot-no>
<currency>EUR</currency>
<server-locale>Esp</server-locale>
<lax>gross</lax>
<current-impot-no>123358</current-impot-no>
<product-lineitems>
<product-lineitem>
<price>450</price>
<red>6.50</red>
<Small-price>39.00</Small-price>
<Big-price>3229.00</Big-price>
<lineitem-text>Grand create</lineitem-text>
<basis>234.00</basis>
</product-lineitem>
</product-lineitems>
<product-lineitems>
<product-lineitem>
<price>432</price>
<red>12</red>
<Small-price>44.00</Small-price>
<Big-price>34.00</Big-price>
<lineitem-text>Small create</lineitem-text>
<basis>44.00</basis>
</product-lineitem>
</product-lineitems>
</impot>
</impots>
您无法检索后代,因为您没有包含命名空间http://www.google.com/xml/impot//20016-02-31
。
这是代码应该如何。
XNamespace ns = "http://www.google.com/xml/impot//20016-02-31";
var results = xDocument.Descendants(ns + "impot");
然后,您需要修改查询以检索所需的元素。
这是样本。我认为product-lineitems
只有一个孩子product-lineitem
。
var results = xDocument.Descendants(ns + "impot").Select(x => new {
ImpotNo = x.Attribute("impot-no")?.Value,
ProductLineItems = x.Descendants(ns + "product-lineitems").Select(y => new
{
Item = y.Descendants(ns + "product-lineitem").Select(z => new
{
Price = z.Element(ns + "price")?.Value,
SmallPrice = z.Element(ns + "Small-price")?.Value,
BigPrice = z.Element(ns + "Big-price")?.Value,
}).FirstOrDefault()
})
});
foreach (var result in results)
{
foreach (var productLine in result.ProductLineItems)
{
dataToBeWritten.Append(result.ImpotNo);
dataToBeWritten.Append(";");
dataToBeWritten.Append(productLine.Item.Price);
dataToBeWritten.Append(";");
dataToBeWritten.Append(productLine.Item.SmallPrice);
dataToBeWritten.Append(";");
dataToBeWritten.Append(productLine.Item.BigPrice);
dataToBeWritten.Append(";");
dataToBeWritten.Append(0);
dataToBeWritten.Append(Environment.NewLine);
}
}
好吧,首先我尝试重新格式化你的XML,使其更具可读性,但标签结构似乎仍然错误......
<impots
xmlns="http://www.google.com/xml/impot//20016-02-31">
<impot impot-no="W0110891258">
<impot-date>2017-12-10T22:33:35.000Z</impot-date>
<prop-by>Yallo</prop-by>
<original-impot-no>891258</original-impot-no>
<currency>EUR</currency>
<server-locale>Esp</server-locale>
<lax>gross</lax>
<current-impot-no>123358</current-impot-no>
<product-lineitems>
<product-lineitem>
<price>450</price>
<red>6.50</red>
<Small-price>39.00</Small-price>
<Big-price>3229.00</Big-price>
<lineitem-text>Grand create</lineitem-text>
<basis>234.00</basis>
-
</product-lineitems>
-
</product-lineitem>
<product-lineitems>
<product-lineitem>
<price>432</price>
<red>12</red>
<Small-price>44.00</Small-price>
<Big-price>34.00</Big-price>
<lineitem-text>Small create</lineitem-text>
<basis>44.00</basis>
</product-lineitems>
</product-lineitem>
尽管如此,我猜这条线是不正确的,因为“impot-no”是一个属性......
impot-no = (string)x.Element("impot impot-no")
也许你的意思是......
impot-no = (string)x.Attribute("impot-no").Value
通过内存 - 希望这是检索属性的正确方法。
查看以下代码。请注意使用SelectMany
获取impot项目以构建所需的对象模型。
XNamespace ns = "http://www.google.com/xml/impot//20016-02-31";
var results = xDocument.Descendants(ns + "impot")
.SelectMany(impot => impot.Descendants(impot.Name.Namespace + "product-lineitem")
.Select(item => new {
ImpotNo = (string)impot.Element(impot.Name.Namespace + "original-impot-no"),
Price = (string)item.Element(item.Name.Namespace + "price"),
SmallPrice = (string)item.Element(item.Name.Namespace + "Small-price"),
BigPrice = (string)item.Element(item.Name.Namespace + "Big-price"),
})
).ToList();
for (int i = 0; i < results.Count; i++) {
dataToBeWritten.Append(results[i].ImpotNo);
dataToBeWritten.Append(";");
dataToBeWritten.Append(results[i].Price);
dataToBeWritten.Append(";");
dataToBeWritten.Append(results[i].SmallPrice);
dataToBeWritten.Append(";");
dataToBeWritten.Append(results[i].BigPrice);
dataToBeWritten.Append(";");
dataToBeWritten.Append(0);
dataToBeWritten.Append(Environment.NewLine);
}
另请注意用于属性的语法。