【问题标题】:Converting nodes with the same name to text with c#使用c#将具有相同名称的节点转换为文本
【发布时间】:2016-12-17 14:01:44
【问题描述】:

我找到了这个指南,将我的 xml 文件转换为 csv:https://msdn.microsoft.com/en-us/library/mt693157.aspx

在部分节点同名之前一切正常

 <ProductSpecification>
                    <Property>
                      <Name>CLEANING PERFORMANCE</Name>
                      <Value>-</Value>
                    </Property>
                    <Property>
                      <Name>COLOUR</Name>
                      <Value>White</Value>
                    </Property>
                    <Property>
                      <Name>DIMENSIONS (H x W x D cm)</Name>
                      <Value>85 x 60 x 45</Value>
                    </Property>
                    <Property>
                      <Name>DISH SETTING CAPACITY</Name>
                      <Value>-</Value>
                    </Property>
</ProductSpecification>

如果我尝试使用

(string)el.Element("ProductSpecification"),

我的整个文本组合成一大堆字母,节点之间没有任何空格:

CLEANING PERFORMANCE-COLOURWhiteDIMENSIONS (H x W x D cm)85 x 60 x 45DISH SETTING CAPACITY-

如果我尝试使用

(string)el.Element("ProductSpecification").Element("Property"),

我只是得到一个错误,没有任何错误的解释

我需要的结果是:

Cleaning Performance
-
Colour
White

Soo...我尝试了所有我能想到的方法,但无法在节点之间写出带有空格的文本 编辑:现在添加我的整个脚本:

XElement custOrd = XElement.Load("_output.xml");
            string csv =
                (from el in custOrd.Elements("PriceCatalog").Elements("ListofCatalogDetails").Elements("CatalogItem").Elements("Product").Elements("ProductSpec").Elements("ProductDetails")
                 select
         String.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16}, \"{17}\"{18}",
             (string)el.Element("ProductID"),
             (string)el.Element("PartNumber"),
             (string)el.Element("Description"),
             (string)el.Element("LongDesc"),
             (string)el.Element("Manufacturer"),
             (string)el.Element("Category01"),
             (string)el.Element("Category02"),
             (string)el.Element("Category03"),
             (string)el.Element("CategoryVAT"),
             (string)el.Element("PeriodofWarranty"),
             (string)el.Element("Qty").Element("QtyAvailable"),
             (string)el.Element("UnitPrice"),
             (string)el.Element("VatRate"),
             (string)el.Element("Weight"),
             (string)el.Element("Height"),
             (string)el.Element("Width"),
             (string)el.Element("Length"),
             (string)el.Element("ProductSpecification"),
             Environment.NewLine

         )
                )
                .Aggregate(
                    new StringBuilder(),
                    (sb, s) => sb.Append(s),
                    sb => sb.ToString()
                );
            Console.WriteLine(csv);

EDIT02:我刚刚发现有些项目没有“ProductSpecification”节点,但是 c# 没有给出任何错误,但是如果我使用“ProductSpecification.Property” - 它会崩溃。现在我只需要以某种方式绕过它

【问题讨论】:

  • 而具体的报错信息是?
  • 使用 "Elements("Property")" 而不是 "Element("Property")" (string)el.Element("ProductSpecification").Elements("Property")
  • 卢克,我明白了:System.NullReferenceException was unhandled HResult=-2147467261 Message=Object reference not set to an instance of an object.
  • Vijai,我试过了,但它不起作用,我得到:Cannot convert type 'System.Collections.Generic.IEnumerable&lt;System.Xml.Linq.XElement&gt;' to 'string'

标签: c# xml linq csv nodes


【解决方案1】:

您可以像这样遍历 XML:

var doc = XDocument.Parse(xml);
foreach (var property in doc.Element("ProductSpecification").Elements("Property"))
{
    foreach(var element in property.Descendants())
    {
        Console.WriteLine(element.Value);
    }
}

这将产生以下结果:

CLEANING PERFORMANCE
-
COLOUR
White
DIMENSIONS (H x W x D cm)
85 x 60 x 45
DISH SETTING CAPACITY

【讨论】:

  • 我需要另一个循环,是否可以在读取节点时添加一行以使用“_”或任何内容分割节点?我将整个脚本附加到我的原始帖子中
【解决方案2】:

试试这个,我没调试过

XElement custOrd = XElement.Load("yourxml.xml");

string csv =
    (from el in custOrd.Element("ProductSpecification").Elements("Property")
    select
        String.Format("{0},{1}",
            (string)el.Element("Name"),
            (string)el.Element("Value"),
            Environment.NewLine
        )
    )
    .Aggregate(
        new StringBuilder(),
        (sb, s) => sb.Append(s),
        sb => sb.ToString()
    );
Console.WriteLine(csv);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多