【问题标题】:Parsing XML through to CSV in C# using linq使用 linq 在 C# 中将 XML 解析为 CSV
【发布时间】:2019-12-28 14:46:56
【问题描述】:

我正在尝试将 xml 文件的属性解析为 csv 文件,代码检查并运行没有错误,并且生成了输出 CSV 文件但不包含数据

我认为问题可能在于元素的附加,因为当我尝试将另一个声明的字符串附加到字符串生成器时,它仍然没有打印任何内容。我也尝试过更改后代以防万一这里出现错误但似乎没有任何效果

using System;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Text;


namespace Test
{
    class Program
    {
        public static void Main()
        {
            StringBuilder sb = new StringBuilder();
            string delimiter = ",";
            XDocument.Load(@"C:\Users\livingss\Desktop\XML - CSV\xml\Xml\----------.xml").Descendants("Param").ToList().ForEach(
                element => sb.Append(element.Attribute("Name").Value
                + delimiter
                + element.Attribute("PNum").Value
                + "\r\n"));

            Console.WriteLine(sb);
            StreamWriter sw = new StreamWriter(@"C:\Users\livingss\Desktop\XML - CSV\Result.csv");
            sw.WriteLine(sb.ToString());
            sw.Close();
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<Equipment EType="0000" Name="PlaceHolder" Version="$Revision: 2$" xmlns="urn:equipment-type">
    <EqAttributes />
    <EqVariant />
    <EqModules />
    <EqLogging />
    <EqParameters>
        <Param Name="Not Used" PNum="1">
            <Desc>Spare</Desc>
        </Param>
        <Param Name="Equipment Status" PNum="2" Min="0" Max="8" Un="1">
            <vMap>
                <Opt Name="Stopped">0</Opt>
                <Opt Name="Starting">1</Opt>
                <Opt Name="Running">2</Opt>
                <Opt Name="Stopping">3</Opt>
                <Opt Name="Standby">4</Opt>
                <Opt Name="Idle">5</Opt>
                <Opt Name="Sleep">6</Opt>
                <Opt Name="Hibernate">7</Opt>
                <Opt Name="Faulted">8</Opt>
            </vMap>
        </Param>
        <Param Name="Not Used" PNum="3" Min="0" Max="5" Un="3">
            <Desc>Spare</Desc>
        </Param>
    </EqParameters>
    <EqConfiguration>
    </EqConfiguration>
</Equipment>

预期的输出应该是 Param 的属性,即 'Name 和 'PNum',第一行的输出应该是 'Not Used,1'

【问题讨论】:

  • 你确定你从调用Descendants(""Param")得到任何结果吗?因为在我看来,您似乎在枚举一个空列表。我尝试在根据您的描述创建的虚拟 XML 上执行您的代码,然后它工作正常。
  • 我已经修改为包含我使用的 XML 文件,希望对您有所帮助

标签: c# xml linq csv parsing


【解决方案1】:

对我来说,问题在于您编写文件的方式。 尝试替换它:

 StreamWriter sw = new StreamWriter(@"C:\Users\livingss\Desktop\XML - CSV\Result.csv");
 sw.WriteLine(sb.ToString());
 sw.Close();

这样:

 var path = @"C:\Users\livingss\Desktop\XML - CSV\Result.csv";
 File.WriteAllText(path, sb.ToString());

【讨论】:

  • 仍然创建了一个没有数据的 CSV 文件
【解决方案2】:

您应该添加命名空间并在Descendants 调用中使用它:

XNamespace urn="urn:equipment-type";     

XDocument.Load(filePath).Descendants(urn + "Param").ToList().ForEach(...

如果没有命名空间,我也不会得到任何要枚举的结果。

【讨论】:

  • 那不只是将字符串"urn:equipment-typeParam" 创建为arg 吗?这似乎不对。您的意思是在此处放置逗号而不是加号吗?
  • 不,这就是您创建XName in a namespace 的方式。 urn 不是字符串,因此它与字符串连接不同。
  • 嗯。我明白你的意思,是的。我没有注意到 urn 不是字符串。非常不直观,这似乎是如何使用字符串连接并最终以XName...
【解决方案3】:

你去吧!

StringBuilder sb = new StringBuilder();
string delimiter = ",";

XmlDocument doc = new XmlDocument();
doc.Load(@"file.xml");
var paramElements = doc.GetElementsByTagName("Param");
for (int i = 0; i < paramElements.Count; i++)
{
    var currentElt = paramElements.Item(i);
    sb.Append(currentElt.Attributes.GetNamedItem("Name").Value);
    sb.Append(delimiter);
    sb.Append(currentElt.Attributes.GetNamedItem("PNum").Value);
    sb.AppendLine();
}

var path = @"Result.csv";
File.WriteAllText(path, sb.ToString());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 2016-08-23
    相关资源
    最近更新 更多