简体   繁体   中英

C# : Parse XML using XDocument into a csv file

I have several xmls of the format :

<InterConnectResponse>
  <SchemaVersion>2.0</SchemaVersion>
  <ConsumerSubjects>
    <ConsumerSubject subjectIdentifier="Primary">
      <DataSourceResponses>
      <RiskViewProducts>
          <RiskViewAttribResponse>
          <Attributes>
                <Attribute>
                  <Name>CurrAddrTaxValue</Name>
                  <Value>3</Value>
                </Attribute>
                <Attribute>
                  <Name>CurrAddrTaxMarketValue</Name>
                  <Value>2</Value>
                </Attribute>
                <Attribute>
                  <Name>CurrAddrBlockIndex</Name>
                  <Value>0.61</Value>
                </Attribute>
           ------ Many More Attributes ---------
         </Attributes>
         </RiskViewAttribResponse>
     </RiskViewProducts>
     </DataSourceResponses>
    </ConsumerSubject>
  </ConsumerSubjects>
</InterConnectResponse> 

I want to parse only specific attributes from the above xml. So I used the below logi. But how do I save the result of the values ( Only Values not Names ) as a csv file ?

 var document = XDocument.Parse(str3); // or `= XDocument.Parse(xml);`
 var attributesToRead = new[] { "CurrAddrTaxValue", "CurrAddrTaxMarketValue", "PrevAddrTaxValue", "PrevAddrAVMValue", "AddrChangeCount60", "DerogSeverityIndex", "LienFiledCount03", "LienSmallClaimsFiledTotal", "EvictionCount12", "NonDerogCount", "NonDerogCount12", "InquiryPersonalFinanceRecent", "HighRiskCreditActivity", "SubPrimeOfferRequestCount", "SubPrimeOfferRequestCount60" };
 var productsElements = document.XPathSelectElements("InterConnectResponse/ConsumerSubjects/ConsumerSubject/DataSourceResponses/RiskViewProducts");
 var products = productsElements.Select(product => new
     {
         Attributes = product.XPathSelectElements("RiskViewAttribResponse/Result/Attributes/Attribute").Select(attribute => new
         {
              Name = attribute.XPathSelectElement("Name").Value,
              Value = attribute.XPathSelectElement("Value").Value
          }).Where(attribute => attributesToRead.Contains(attribute.Name))
     });

But How do I write the result into csv that does append when I parse the next xml ? Aso I only want to write the values into csv not the names of the attributes..

So my expected output is :

3, 2, 0.61,  ............

Well your products variable is an IEnumerable of anonymous type which has a property named Attributes . The Attributes property is and IEnumerable of anonymous types again with 2 properties: Name and Value .

You want to write (append to be exact) the contents of all the Value properties to a file, then do this:

var values = products.SelectMany(x => x.Attributes).Select(x => x.Value);
File.AppendAllText("someFileName.csv", string.Join(",", values));

Of course I am making the assumption that your code works until that point and you are just having difficulties appending to csv file.

Have you considered using library for this. Using Cinchoo ETL - an open source ETL lib, you can produce your expected output with few lines of codes. It is stream based, can parse any size xml.

using (var parser = new ChoXmlReader("sample.xml").WithXPath("Attributes/Attribute")
    .WithField("Name", xPath: "Name")
    .WithField("Value", xPath: "value")
    )
{
    using (var writer = new ChoCSVWriter("sample.csv"))
        writer.Write(parser.Select(kvp => kvp.Value).ToExpandoObject());
}

The output is:

3,2,0.61

Disclosure: I'm the author of this library.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM