Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#XML节点缺少元素-尝试另存为CSV_C#_Xml_Csv_Linq To Xml - Fatal编程技术网

C#XML节点缺少元素-尝试另存为CSV

C#XML节点缺少元素-尝试另存为CSV,c#,xml,csv,linq-to-xml,C#,Xml,Csv,Linq To Xml,我发现很多关于将XML另存为CSV的帖子,但我的问题是XML中的某些节点的元素比其他节点少。这导致我的CSV列关闭,这不是很有帮助。我使用的XML数据来自第三方API 这是我的密码: internal static void XmlToCsvFile(XmlDocument doc, string fileName) { var xml = new XDocument(); xml = XDocument.Parse(doc.InnerXml);

我发现很多关于将XML另存为CSV的帖子,但我的问题是XML中的某些节点的元素比其他节点少。这导致我的CSV列关闭,这不是很有帮助。我使用的XML数据来自第三方API

这是我的密码:

    internal static void XmlToCsvFile(XmlDocument doc, string fileName)
    {
        var xml = new XDocument();
        xml = XDocument.Parse(doc.InnerXml);

        StringBuilder sb = new StringBuilder(100000);

        var xmlDocForHeaders = new XmlDocument();
        xmlDocForHeaders.InnerXml = xml.Root.FirstNode.ToString();

        var xdocForHeaders = XDocument.Parse(xmlDocForHeaders.InnerXml);

        foreach (var element in xdocForHeaders.Elements().Elements())
        {
            sb.Append($"{element.Name},");
        }

        sb.Append("\n");

        foreach (XElement node in xml.Descendants("Table"))
        {
            foreach (XElement innerNode in node.Elements())
            {
                foreach (XElement elements in innerNode.Elements())
                {
                    sb.Append($"\"{elements.Value}\",");
                }

                sb.Append("\n");
            }

            sb.Remove(sb.Length - 1, 1);
            sb.AppendLine();
        }

        var csvOut = sb.ToString();
        SaveDataToCsvFile(csvOut);
    }
我知道我不需要将XmlDocument转换为XDocument,但这在当时似乎更容易

任何帮助都将不胜感激

谢谢

编辑:

以下是XML数据的示例:

<Table>
  <Record>
    <StoreID>43</StoreID>
    <StoreName>30455 Juniper</StoreName>
    <Disabled>0</Disabled>
    <Abbreviation>UC30455</Abbreviation>
    <ManagerEmployeeID>297</ManagerEmployeeID>
    <ManagerCommissionable>false</ManagerCommissionable>
    <Address>400 Green St.</Address>
    <City>Juniper</City>
    <StateProv>WA</StateProv>
    <ZipPostal>47895</ZipPostal>
    <Country>United States</Country>
    <PhoneNumber>8056954823</PhoneNumber>
    <FaxNumber>5085236524</FaxNumber>
    <DistrictNameJuniper South</DistrictName>
    <RegionName>High Hills Region</RegionName>
    <ChannelName>West Market</ChannelName>
    <StoreType>1/2 Tier-PP</StoreType>
    <GLCode>5862</GLCode>
    <SquareFootage>1100</SquareFootage>
    <LocationCode>MX029</LocationCode>
    <Latitude>49.5236458952</Latitude>
    <Longitude>-192.532150000</Longitude>
    <AddressVerified>Not Verified</AddressVerified>
    <TimeZone>(GMT-08:00) West Time (US &amp; Canada)</TimeZone>
    <AdjustDST>true</AdjustDST>
    <CashPolicy>Single-Drawer</CashPolicy>
    <MaxCashDrawer>0.0000</MaxCashDrawer>
    <Serial_on_OE>false</Serial_on_OE>
    <Phone_on_OE>true</Phone_on_OE>
    <PAW_on_OE>true</PAW_on_OE>
    <Comment_on_OE>false</Comment_on_OE>
    <HideCustomerAddress>false</HideCustomerAddress>
    <EmailAddress>donotreply@email.com</EmailAddress>
    <GeneralLocationNotes>Mon-Sat 9am-8pm, Sun 12pm-5pm</GeneralLocationNotes>
    <SaleInvoiceComment />
    <BankDetails />
    <Taxes>UT - Sales Tax 6.6%, 1.9% E911 Fee (WA)</Taxes>
    <Rent>0.0000</Rent>
    <PropertyTaxes>0.0000</PropertyTaxes>
    <InsuranceAmount>0.0000</InsuranceAmount>
    <OtherCharges>0.0000</OtherCharges>
    <DepositTaken>0.0000</DepositTaken>
    <LeaseNotes />
    <InsuranceCompany />
    <LandlordNotes />
    <LandlordName>COMPANY-JUNIPER/60144582</LandlordName>
    <UseLocationEmail>true</UseLocationEmail>
    <LocationEntityID>25367</LocationEntityID>
  </Record>
  <Record>
    <StoreID>107</StoreID>
    <StoreName>9589 CLC Go Company.com</StoreName>
    <Disabled>0</Disabled>
    <Abbreviation>CL9589</Abbreviation>
    <ManagerEmployeeID>853</ManagerEmployeeID>
    <ManagerCommissionable>false</ManagerCommissionable>
    <Address>9852 Bland Banks Blvd.</Address>
    <City>Honneyton</City>
    <StateProv>MI</StateProv>
    <ZipPostal>69421</ZipPostal>
    <Country>USA</Country>
    <PhoneNumber>9595525214</PhoneNumber>
    <FaxNumber>3625485236</FaxNumber>
    <DistrictName>Recovery Services</DistrictName>
    <RegionName>zRetail Support</RegionName>
    <ChannelName>zRetail Support</ChannelName>
    <StoreType>Care Center</StoreType>
    <GLCode>0356</GLCode>
    <SquareFootage>2163</SquareFootage>
    <AddressVerified>Not Verified</AddressVerified>
    <TimeZone>(GMT-07:00) Central Time (US &amp; Canada)</TimeZone>
    <AdjustDST>true</AdjustDST>
    <CashPolicy>Single-Drawer</CashPolicy>
    <MaxCashDrawer>0.0000</MaxCashDrawer>
    <Serial_on_OE>false</Serial_on_OE>
    <Phone_on_OE>true</Phone_on_OE>
    <PAW_on_OE>false</PAW_on_OE>
    <Comment_on_OE>false</Comment_on_OE>
    <HideCustomerAddress>false</HideCustomerAddress>
    <EmailAddress>donotreply@email.com</EmailAddress>
    <GeneralLocationNotes />
    <SaleInvoiceComment />
    <BankDetails />
    <Taxes>MI - Honneyton</Taxes>
    <Rent>0.0000</Rent>
    <PropertyTaxes>0.0000</PropertyTaxes>
    <InsuranceAmount>0.0000</InsuranceAmount>
    <OtherCharges>0.0000</OtherCharges>
    <DepositTaken>0.0000</DepositTaken>
    <LeaseNotes />
    <InsuranceCompany />
    <LandlordNotes />
    <LandlordName />
    <UseLocationEmail>true</UseLocationEmail>
    <LocationEntityID>25397</LocationEntityID>
  </Record>
</Table>

43
30455刺柏
0
UC30455
297
假的
格林街400号。
杜松
华盛顿州
47895
美国
8056954823
5085236524

下面是我在评论中所说内容的一个快速说明。由于您似乎是一次性完成这项工作的,因此可以将XML解析为匿名类型的集合,然后遍历该集合以写出CSV

简单的例子:

var records = xml.Descedants("Record").Select(r => new
              {
                  StoreID = (string)r.Element("StoreID"),
                  StoreName = (string)r.Element("StoreName"),
                  // other elements
              };
注意显式转换为字符串-如果缺少元素,这将返回null,这将很好地解决某些记录中缺少某些元素的问题。否则,您将不得不编写一堆额外的代码来检查缺少的元素,这将变得非常难看

一旦您拥有匿名类型的集合,您就可以遍历它们以写出CSV:

foreach(var record in records)
{
    // Here you can access the individual properties in the currently selected record
}

下面是我在评论中所说内容的一个快速说明。由于您似乎是一次性完成这项工作的,因此可以将XML解析为匿名类型的集合,然后遍历该集合以写出CSV

简单的例子:

var records = xml.Descedants("Record").Select(r => new
              {
                  StoreID = (string)r.Element("StoreID"),
                  StoreName = (string)r.Element("StoreName"),
                  // other elements
              };
注意显式转换为字符串-如果缺少元素,这将返回null,这将很好地解决某些记录中缺少某些元素的问题。否则,您将不得不编写一堆额外的代码来检查缺少的元素,这将变得非常难看

一旦您拥有匿名类型的集合,您就可以遍历它们以写出CSV:

foreach(var record in records)
{
    // Here you can access the individual properties in the currently selected record
}

您可以提供示例xml吗?为什么不创建一个类来保存数据,然后通过LINQ将xml解析到类中,适当地处理缺少的元素,然后将类的集合写成CSV?或者甚至写成一个匿名类型,然后处理成CSV文件。这非常聪明。我还需要添加子级别。你知道怎么做吗?类似于递归函数。您能提供示例xml吗?为什么不创建一个类来保存数据,然后通过LINQ to xml将xml解析到类中,适当地处理缺少的元素,然后将这些类的集合写成CSV?格式,甚至是一个匿名类型,然后可以将其处理成CSV文件。这非常聪明。我还需要添加子级别。你知道怎么做吗?类似递归函数的东西。非常感谢!您的回答让我走上了正确的轨道,但因为我需要根据输入的数据动态创建密钥(CSV头是动态的),所以我最终使用字典来定义数据的外观,方法是迭代所有节点密钥并添加任何新的密钥。然后,我可以为每个节点将数据添加到字典中。这似乎效果不错,但我觉得可能有点凌乱。任何关于清理的建议都将不胜感激!看看我上面的编辑。再次感谢你的帮助!!非常感谢!您的回答让我走上了正确的轨道,但因为我需要根据输入的数据动态创建密钥(CSV头是动态的),所以我最终使用字典来定义数据的外观,方法是迭代所有节点密钥并添加任何新的密钥。然后,我可以为每个节点将数据添加到字典中。这似乎效果不错,但我觉得可能有点凌乱。任何关于清理的建议都将不胜感激!看看我上面的编辑。再次感谢你的帮助!!