I have an XML file with 3-4 levels deep of nested children. Some of the children have either a missing element or an extra element. I am struggling with automating reading the xml x children deep and also creating the appropriate flat delimited records to match the parent item. I am using VS 2015 and C# in a winform application and the end result of the file is that they record structure needs to be the same for all the items regardless of any missing or blank elements. Below is my button click event along with a sampling of the data I am dealing with. Note ITEM 1 has 1 Zoning Node, ITEM 2 has 2 Zoning Nodes and ITEM 3 has 0 Zoning Nodes. The result throws off my column Counts in the delimited file for when I bring it into EXCEL for example.
private void button1_Click(object sender, EventArgs e)
{
try
{
string sDelimiter = "";
string sNodeName = "";
string sChildNodeName = "";
switch (uicmbDelimiter.Text)
{
case "TAB":
sDelimiter = "\t";
break;
case "PIPE":
sDelimiter = "|";
break;
case "COMMA":
sDelimiter = ",";
break;
default:
sDelimiter = ",";
break;
}
string csvstring = "";
StreamWriter csv = new StreamWriter(this.uitxtXMLFile.Text + ".out");
XmlDocument doc = new XmlDocument();
doc.Load(this.uitxtXMLFile.Text);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ab", "http://www.revenue.wi.gov/slf");
XmlNodeList nodelist = doc.SelectNodes("//ab:Item", nsmgr);
foreach (XmlNode xnfields in nodelist)
{
foreach (XmlNode childnode in xnfields.ChildNodes)
{
if (childnode.ChildNodes.Count > 1)
{
foreach (XmlNode children in childnode.ChildNodes)
{
csvstring +=children.LocalName + sDelimiter;
}
}
else
{
csvstring += childnode.LocalName + sDelimiter;
}
}
csv.WriteLine(csvstring);
csvstring = "";
break;
}
csvstring = "";
foreach (XmlNode xn in nodelist)
{
foreach (XmlNode childnode in xn.ChildNodes)
{
if (childnode.ChildNodes.Count > 1)
{
foreach (XmlNode children in childnode.ChildNodes)
{
if ((sChildNodeName != children.LocalName) && sChildNodeName !="" )
{
csvstring += sDelimiter + children.InnerText;
}
else
{
csvstring += children.InnerText;
}
sChildNodeName = children.LocalName;
}
}
else
{
csvstring += childnode.InnerText;
}
///////////
///
///////////
if ((sNodeName != childnode.LocalName))
{
csvstring += sDelimiter;
}
sNodeName = childnode.LocalName;
}
csv.WriteLine(csvstring);
csvstring = "";
sNodeName = "";
sChildNodeName = "";
}
csv.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.Message);
}
}
<?xml version="1.0" encoding="utf-8"?>
<CountyRolls xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.revenue.wi.gov/slf">
<Municipality>
<MunicipalityNumber>002</MunicipalityNumber>
<Item>
<RecordNumber>1</RecordNumber>
<PropertyInfo>
<LocalID1>1-00001-000</LocalID1>
<LocalID2>1</LocalID2>
<Zoning>EXCLUSIVE AGRICULTURE DISTRICT</Zoning>
<Town>16</Town>
<Range>05</Range>
<RangeDirection>W</RangeDirection>
<Section>01</Section>
<Quarter40>NE</Quarter40>
<Quarter160>NE</Quarter160>
<Legal>FRAC NE1/4 OF NE1/4</Legal>
<RecordingDocuments>
<Book>0</Book>
<Page>0</Page>
<DocumentNumber>1569517</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>589</Book>
<Page>204</Page>
<DocumentNumber>868152</DocumentNumber>
</RecordingDocuments>
</PropertyInfo>
<OwnerAndAddressInfo>
<MailingAddress>
<USAddress>
<AddressLine1>N4929 COUNTY ROAD J</AddressLine1>
<City>ROCKLAND</City>
<State>WI</State>
<ZIPCode>54653</ZIPCode>
</USAddress>
</MailingAddress>
<Owner>
<Individual>
<Name>
<FirstName>DAVID</FirstName>
<LastName>AXELSEN IRREVOCABLE LIVING TRUST</LastName>
</Name>
<Address>
<USAddress>
<AddressLine1>N4929 COUNTY ROAD J</AddressLine1>
<City>ROCKLAND</City>
<State>WI</State>
<ZIPCode>54653</ZIPCode>
</USAddress>
</Address>
</Individual>
</Owner>
<Owner>
<Individual>
<Name>
<FirstName>RHEA</FirstName>
<LastName>AXELSEN IRREVOCABLE LIVING TRUST</LastName>
</Name>
<Address>
<USAddress>
<AddressLine1>N4929 COUNTY ROAD J</AddressLine1>
<City>ROCKLAND</City>
<State>WI</State>
<ZIPCode>54653</ZIPCode>
</USAddress>
</Address>
</Individual>
</Owner>
<SiteAddress>
<AddressLine1>JACKPOT AVE</AddressLine1>
<City>ROCKLAND</City>
<State>WI</State>
<ZIPCode>54653</ZIPCode>
</SiteAddress>
</OwnerAndAddressInfo>
<ValuationInfo>
<RealProperty>
<Class4>
<Acres>8.000</Acres>
<LandValue>1200</LandValue>
<ImprovementsValue>0</ImprovementsValue>
</Class4>
<Class5M>
<Acres>31.460</Acres>
<LandValue>50300</LandValue>
<ImprovementsValue>0</ImprovementsValue>
</Class5M>
<ClassTotal>
<Acres>39.460</Acres>
<LandValue>51500</LandValue>
<ImprovementsValue>0</ImprovementsValue>
</ClassTotal>
</RealProperty>
</ValuationInfo>
<JurisdictionInfo>
<County>
<CountyName>32 La Crosse</CountyName>
<CountyRate>0.004068228</CountyRate>
<CountyTax>209.51</CountyTax>
</County>
<Municipality>
<MuniName>Town of Bangor</MuniName>
<MuniNumber>32002</MuniNumber>
<MunicipalRate>0.002443039</MunicipalRate>
<MunicipalTax>125.82</MunicipalTax>
</Municipality>
<School>
<Code>320245</Code>
<Rate>0.009154910</Rate>
<Tax>471.48</Tax>
</School>
<Tech>
<Code>000200</Code>
<Rate>0.001590738</Rate>
<Tax>81.92</Tax>
</Tech>
</JurisdictionInfo>
<TaxSummary>
<LandTaxableTotal>51500</LandTaxableTotal>
<ImprovementsTaxableTotal>0</ImprovementsTaxableTotal>
<TotalTaxableValue>51500</TotalTaxableValue>
<EstimatedFairMarketValue>0</EstimatedFairMarketValue>
<StateTax>8.86</StateTax>
<OccupationalTax>0</OccupationalTax>
<ForestTaxable>0</ForestTaxable>
<BORValue>51500</BORValue>
<PrivateForestCropTax>0.00</PrivateForestCropTax>
<ManagedForestLawTax>0.00</ManagedForestLawTax>
<TaxTotal>897.59</TaxTotal>
<SchoolCredit>95.43</SchoolCredit>
<LotteryCredit>0.00</LotteryCredit>
<FirstDollarCredit>0.00</FirstDollarCredit>
<SpecialAssessment>
<SpecialAssessmentDesc>No special charge applies to parcel.</SpecialAssessmentDesc>
<SpecialAssessmentCharge>0</SpecialAssessmentCharge>
</SpecialAssessment>
<DelinquentUtilityCharges>0</DelinquentUtilityCharges>
<NetTax>897.59</NetTax>
<Payment>0</Payment>
<AmountDue>897.59</AmountDue>
<PriorYearChargebacks>
<Total>0</Total>
</PriorYearChargebacks>
<StateAssessedTelco>0</StateAssessedTelco>
</TaxSummary>
</Item>
<Item>
<RecordNumber>2</RecordNumber>
<PropertyInfo>
<LocalID1>1-00003-001</LocalID1>
<LocalID2>4</LocalID2>
<Zoning>CONDITIONAL ZONING </Zoning>
<Zoning>EXCLUSIVE AGRICULTURE DISTRICT</Zoning>
<Town>16</Town>
<Range>05</Range>
<RangeDirection>W</RangeDirection>
<Section>01</Section>
<Quarter40>NE</Quarter40>
<Quarter160>SW</Quarter160>
<Legal>CERTIFIED SURVEY MAP NO. 64 VOL 7 LOT 1 DOC NO. 1159544</Legal>
<RecordingDocuments>
<Book>7</Book>
<Page>64</Page>
<DocumentNumber>1159544</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>872</Book>
<Page>36</Page>
<DocumentNumber>1039008</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>1129</Book>
<Page>264</Page>
<DocumentNumber>1152228</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>1140</Book>
<Page>558</Page>
<DocumentNumber>1156940</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>1156</Book>
<Page>31</Page>
<DocumentNumber>1163596</DocumentNumber>
</RecordingDocuments>
</PropertyInfo>
<OwnerAndAddressInfo>
<MailingAddress>
<USAddress>
<AddressLine1>N4746 COUNTY ROAD J</AddressLine1>
<City>ROCKLAND</City>
<State>WI</State>
<ZIPCode>54653</ZIPCode>
</USAddress>
</MailingAddress>
<Owner>
<Individual>
<Name>
<FirstName>SCOTT R</FirstName>
<LastName>MILDE</LastName>
</Name>
<Address>
<USAddress>
<AddressLine1>N4746 COUNTY ROAD J</AddressLine1>
<City>ROCKLAND</City>
<State>WI</State>
<ZIPCode>54653</ZIPCode>
</USAddress>
</Address>
</Individual>
</Owner>
<Owner>
<Individual>
<Name>
<FirstName>SUSAN T</FirstName>
<LastName>MILDE</LastName>
</Name>
</Individual>
</Owner>
<SiteAddress>
<AddressLine1>N4746 COUNTY ROAD J</AddressLine1>
<City>ROCKLAND</City>
<State>WI</State>
<ZIPCode>54653</ZIPCode>
</SiteAddress>
</OwnerAndAddressInfo>
<ValuationInfo>
<RealProperty>
<Class1>
<Acres>1.760</Acres>
<LandValue>13800</LandValue>
<ImprovementsValue>127400</ImprovementsValue>
</Class1>
<ClassTotal>
<Acres>1.760</Acres>
<LandValue>13800</LandValue>
<ImprovementsValue>127400</ImprovementsValue>
</ClassTotal>
</RealProperty>
</ValuationInfo>
<JurisdictionInfo>
<County>
<CountyName>32 La Crosse</CountyName>
<CountyRate>0.004068228</CountyRate>
<CountyTax>574.43</CountyTax>
</County>
<Municipality>
<MuniName>Town of Bangor</MuniName>
<MuniNumber>32002</MuniNumber>
<MunicipalRate>0.002443039</MunicipalRate>
<MunicipalTax>344.96</MunicipalTax>
</Municipality>
<School>
<Code>320245</Code>
<Rate>0.009154910</Rate>
<Tax>1292.67</Tax>
</School>
<Tech>
<Code>000200</Code>
<Rate>0.001590738</Rate>
<Tax>224.61</Tax>
</Tech>
</JurisdictionInfo>
<TaxSummary>
<LandTaxableTotal>13800</LandTaxableTotal>
<ImprovementsTaxableTotal>127400</ImprovementsTaxableTotal>
<TotalTaxableValue>141200</TotalTaxableValue>
<EstimatedFairMarketValue>143200</EstimatedFairMarketValue>
<StateTax>24.30</StateTax>
<OccupationalTax>0</OccupationalTax>
<ForestTaxable>0</ForestTaxable>
<BORValue>141200</BORValue>
<PrivateForestCropTax>0.00</PrivateForestCropTax>
<ManagedForestLawTax>0.00</ManagedForestLawTax>
<TaxTotal>2460.97</TaxTotal>
<SchoolCredit>261.64</SchoolCredit>
<LotteryCredit>136.65</LotteryCredit>
<FirstDollarCredit>72.66</FirstDollarCredit>
<SpecialAssessment>
<SpecialAssessmentDesc>No special charge applies to parcel.</SpecialAssessmentDesc>
<SpecialAssessmentCharge>0</SpecialAssessmentCharge>
</SpecialAssessment>
<DelinquentUtilityCharges>0</DelinquentUtilityCharges>
<NetTax>2251.66</NetTax>
<Payment>0</Payment>
<AmountDue>2251.66</AmountDue>
<PriorYearChargebacks>
<Total>0</Total>
</PriorYearChargebacks>
<StateAssessedTelco>0</StateAssessedTelco>
</TaxSummary>
</Item>
<Item>
<RecordNumber>3</RecordNumber>
<PropertyInfo>
<LocalID1>1-00004-000</LocalID1>
<LocalID2>5</LocalID2>
<Town>16</Town>
<Range>05</Range>
<RangeDirection>W</RangeDirection>
<Section>01</Section>
<Quarter40>NE</Quarter40>
<Quarter160>SE</Quarter160>
<Legal>SE1/4 FRAC NE1/4</Legal>
<RecordingDocuments>
<Book>870</Book>
<Page>575</Page>
<DocumentNumber>1038082</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>872</Book>
<Page>36</Page>
<DocumentNumber>1039008</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>1129</Book>
<Page>264</Page>
<DocumentNumber>1152228</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>1140</Book>
<Page>558</Page>
<DocumentNumber>1156940</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>1336</Book>
<Page>55</Page>
<DocumentNumber>1234542</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>1336</Book>
<Page>523</Page>
<DocumentNumber>1234736</DocumentNumber>
</RecordingDocuments>
<RecordingDocuments>
<Book>1385</Book>
<Page>535</Page>
<DocumentNumber>1254119</DocumentNumber>
</RecordingDocuments>
</PropertyInfo>
<OwnerAndAddressInfo>
<MailingAddress>
<USAddress>
<AddressLine1>230 21ST ST S</AddressLine1>
<City>LA CROSSE</City>
<State>WI</State>
<ZIPCode>54601</ZIPCode>
</USAddress>
</MailingAddress>
<Owner>
<Individual>
<Name>
<FirstName>GALEN W</FirstName>
<LastName>PITTMAN</LastName>
</Name>
<Address>
<USAddress>
<AddressLine1>230 21ST ST S</AddressLine1>
<City>LA CROSSE</City>
<State>WI</State>
<ZIPCode>54601</ZIPCode>
</USAddress>
</Address>
</Individual>
</Owner>
<SiteAddress>
<AddressLine1>COUNTY ROAD J</AddressLine1>
<City>ROCKLAND</City>
<State>WI</State>
<ZIPCode>54653</ZIPCode>
</SiteAddress>
</OwnerAndAddressInfo>
<ValuationInfo>
<RealProperty>
<Class5>
<Acres>9.000</Acres>
<LandValue>11700</LandValue>
<ImprovementsValue>0</ImprovementsValue>
</Class5>
<Class6>
<Acres>31.000</Acres>
<LandValue>99200</LandValue>
<ImprovementsValue>0</ImprovementsValue>
</Class6>
<ClassTotal>
<Acres>40.000</Acres>
<LandValue>110900</LandValue>
<ImprovementsValue>0</ImprovementsValue>
</ClassTotal>
</RealProperty>
</ValuationInfo>
<JurisdictionInfo>
<County>
<CountyName>32 La Crosse</CountyName>
<CountyRate>0.004068228</CountyRate>
<CountyTax>451.17</CountyTax>
</County>
<Municipality>
<MuniName>Town of Bangor</MuniName>
<MuniNumber>32002</MuniNumber>
<MunicipalRate>0.002443039</MunicipalRate>
<MunicipalTax>270.93</MunicipalTax>
</Municipality>
<School>
<Code>320245</Code>
<Rate>0.009154910</Rate>
<Tax>1015.28</Tax>
</School>
<Tech>
<Code>000200</Code>
<Rate>0.001590738</Rate>
<Tax>176.41</Tax>
</Tech>
</JurisdictionInfo>
<TaxSummary>
<LandTaxableTotal>110900</LandTaxableTotal>
<ImprovementsTaxableTotal>0</ImprovementsTaxableTotal>
<TotalTaxableValue>110900</TotalTaxableValue>
<EstimatedFairMarketValue>112500</EstimatedFairMarketValue>
<StateTax>19.09</StateTax>
<OccupationalTax>0</OccupationalTax>
<ForestTaxable>0</ForestTaxable>
<BORValue>110900</BORValue>
<PrivateForestCropTax>0.00</PrivateForestCropTax>
<ManagedForestLawTax>0.00</ManagedForestLawTax>
<TaxTotal>1932.88</TaxTotal>
<SchoolCredit>205.50</SchoolCredit>
<LotteryCredit>0.00</LotteryCredit>
<FirstDollarCredit>0.00</FirstDollarCredit>
<SpecialAssessment>
<SpecialAssessmentDesc>No special charge applies to parcel.</SpecialAssessmentDesc>
<SpecialAssessmentCharge>0</SpecialAssessmentCharge>
</SpecialAssessment>
<DelinquentUtilityCharges>0</DelinquentUtilityCharges>
<NetTax>1932.88</NetTax>
<Payment>0</Payment>
<AmountDue>1932.88</AmountDue>
<PriorYearChargebacks>
<Total>0</Total>
</PriorYearChargebacks>
<StateAssessedTelco>0</StateAssessedTelco>
</TaxSummary>
</Item>
<Chargebacks>
<CurrentYear>
<Total>0</Total>
</CurrentYear>
</Chargebacks>
</Municipality>
</CountyRolls>
xml linq handles null values better. See code below