使用 C# 将 XML 转换为 CSV
Convert a XML to CSV using C#
如何在 C# 中将 XML 文件转换为 CSV 文件,只显示这些标签:<original-impot-no>, <price>, <Small-price>, <Big-price>
?
样例XML代码:表示多行中的一行,每行可能包含多个<product-lineitem>
标签
<?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>
我应该在 y CSV 文件中得到这样的信息:
891258;450;39;229
891258;432;44;34
C#代码:
我遇到此代码的问题是我无法检索 TAG 的下降项 <impot>
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());
}
谁能提出一个解决方案,先谢谢了。
查看以下代码。请注意使用 SelectMany
获取重要的项目以构建所需的对象模型。
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);
}
另请注意用于属性的语法。
好吧,首先我尝试重新格式化您的 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
凭记忆 -- 希望这是检索属性的正确方法。
您有一个无效 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
只有一个 child 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);
}
}
如何在 C# 中将 XML 文件转换为 CSV 文件,只显示这些标签:<original-impot-no>, <price>, <Small-price>, <Big-price>
?
样例XML代码:表示多行中的一行,每行可能包含多个<product-lineitem>
标签
<?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>
我应该在 y CSV 文件中得到这样的信息:
891258;450;39;229
891258;432;44;34
C#代码:
我遇到此代码的问题是我无法检索 TAG 的下降项 <impot>
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());
}
谁能提出一个解决方案,先谢谢了。
查看以下代码。请注意使用 SelectMany
获取重要的项目以构建所需的对象模型。
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);
}
另请注意用于属性的语法。
好吧,首先我尝试重新格式化您的 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
凭记忆 -- 希望这是检索属性的正确方法。
您有一个无效 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
只有一个 child 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);
}
}