我正在使用 C# 将 XML 文件转换为 CSV。我尝试了不同的方法,但无法弄清楚如何访问键名/值对

Posted

技术标签:

【中文标题】我正在使用 C# 将 XML 文件转换为 CSV。我尝试了不同的方法,但无法弄清楚如何访问键名/值对【英文标题】:I am working on converting an XML file to CSV using C#. I have tried different approaches but cannot figure out how to access the key name/value pairs 【发布时间】:2021-11-16 22:44:30 【问题描述】:

这是基本的文件布局。

<InvoiceNo>1065178</InvoiceNo>
<InstallationId>10903</InstallationId>
<CreateDate>2019-03-29T00:00:00</CreateDate>
<AccountNo>123456</AccountNo>
<BalanceDue>1024.40</BalanceDue>
<StatementDate>2019-04-01T00:00:00</StatementDate>
<NoPrint>0</NoPrint>
<Pages>
<Page templatepage="1">
<OtherFields>
<Key name="Instructions1"><Value>Please write your account number on your check!</Value></Key>
<Key name="AgeTitle1"><Value>CURRENT </Value></Key>
<Key name="AgeTitle2"><Value>30 DAYS </Value></Key>
<Key name="AgeTitle3"><Value>60 DAYS </Value></Key>
<Key name="AgeTitle4"><Value>90 DAYS </Value></Key>
</OtherFields>
</Page>
</Pages>
</Invoice>

我可以获取顶层,发票编号,创建日期,但无法获取大部分数据所在的键名/值对。这是我最近尝试将其加载到字典中,它将整个节点加载到一个条目中,我需要将其分开。我没有投入使用字典,这只是我的最新尝试。任何帮助将不胜感激。

string xmlfile = @"C:/data//WDM/CUSTInvoiceData2019032902.xml";
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(xmlfile);


XmlNodeList nodelist = xmldoc.SelectNodes("//*[local-name()='OtherFields']");
Dictionary<string, string> dictXml = new Dictionary<string, string>();

foreach (XmlNode node in nodelist)

    foreach (XmlNode elementpair in node.ChildNodes)
    
        dictXml.Add(elementpair.Attributes["Key name"].Value, 
        elementpair.Attributes["value"].Value);
    

【问题讨论】:

旁白:如果发票有多页怎么办? 让我猜猜:XML 中有很多 Invoice 节点?并展示最终的 CSV 应该是什么样子。 有一个页脚键将下一页标记为继续,并且将在 csv 文件中换行。 【参考方案1】:

使用 Xml 序列化

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication2

    class Program
    
       const string FILE = @"c:\TEMP\TEST.XML";
       static void Main(string[] args)
        
           XmlReader reader = XmlReader.Create(FILE);
           XmlSerializer serializer = new XmlSerializer(typeof(Invoice));
           Invoice invoice = (Invoice)serializer.Deserialize(reader);


        
    
    public class Invoice
    
        public string InvoiceNo  get; set; 
        public string InstallationId  get; set; 
        public DateTime CreateDate  get; set; 
        public string AccountNo  get; set; 
        public decimal BalanceDue  get; set; 
        public DateTime StatementDate  get; set; 
        public int NoPrint  get; set; 

        [XmlArray("Pages")]
        [XmlArrayItem("Page")]
        public Page[] pages  get; set; 

    
    public class Page
    
        [XmlAttribute]
        public int templatepage  get; set; 

        [XmlArray("OtherFields")]
        [XmlArrayItem("Key")]
        public Key[] keys  get; set; 
    
    public class Key
    
        [XmlAttribute]
        public string name  get; set; 
        public Value  Value  get; set; 
    
    public class Value
    
        [XmlText]
        public string value  get; set; 
    


  

【讨论】:

试试这个,我可以进入***项目 invoice.InvoiceNo 例如,但我无法访问 OtherFields 数组? 我在上面添加了图片。 Id 所做的只是在 XML 的开头添加缺少的根标记【参考方案2】:

快完成了

    您在属性名称上失败的不是.Attributes["Key name"],而是.Attributes["name"]

    你必须得到值而不是属性,而且你必须得到子注释值

    foreach (XmlNode elementpair in node.ChildNodes)
    
        var key = elementpair.Attributes["name"].Value;
        var val = elementpair.ChildNodes[0].ChildNodes[0].Value;
        dictXml.Add(key,val);
    

【讨论】:

谢谢你,它看起来很好,直到我遇到一个空值并发现我不能在没有创建自定义字典的情况下在字典中包含 NULL。【参考方案3】:

您正在选择Key 元素并查找两个属性:Key namevalue。但是元素没有具有这些名称的属性。键位于名为name 的属性中,对应的值位于名为Value 的子元素(不是属性)中。

【讨论】:

【参考方案4】:

在您的文件布局中,您忘记在开头添加&lt;Invoice&gt;

这是一种更简单的查询方式。 "//Key"

XmlNodeList nodelist = xmldoc.SelectNodes("//Key");
Dictionary<string, string> dictXml = new Dictionary<string, string>();

foreach (XmlNode node in nodelist)
    dictXml[node.Attributes[0].Value] = node.InnerText;

【讨论】:

以上是关于我正在使用 C# 将 XML 文件转换为 CSV。我尝试了不同的方法,但无法弄清楚如何访问键名/值对的主要内容,如果未能解决你的问题,请参考以下文章

使用 C# 在 XML 文件中转换 CSV

使用 XML 从 XML 转换为 CSV 时 CSV 文件中的标题

有没有办法使用 KnockoutJS 将 XML 文件转换为 CSV?

如何将 XML 转换为 CSV (C#)

当我尝试写入文件时,将 JSON 转换为 XML 错误

C# 将 csv 转换为 xls(使用现有的 csv 文件)