user1514428
user1514428

Reputation: 215

Linq XML reader not working

My XML is this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Supplier xmlns="http://www.example.com/xsd/2012/09/">
  <ID>10302</ID>
  <AccountingUnitId>10000</AccountingUnitId>
  <ShortName>FRE</ShortName>
  <AccountNumber>601100</AccountNumber>
  <BankAddress>...</BankAddress>
  <SupplierAddress>...</SupplierAddress>
  <TermsOfPayment>
    <ID>10009</ID>
    <ShortName>14 NETTO</ShortName>
    <Name>ohne Abzug 14 Tage netto</Name>
    <DaysNet>14</DaysNet>
    <Standard>false</Standard>
    <ValidFrom>1997-01-01T00:00:00.000+01:00</ValidFrom>
  </TermsOfPayment>
  <TermsOfPayment>
    <ID>10040</ID>
    <ShortName>2,0-14</ShortName>
    <Name>2,0 % Skonto innerhalb 14 Tage</Name>
    <DaysForDiscountFirst>14</DaysForDiscountFirst>
    <DiscountPercentFirst>2.0</DiscountPercentFirst>
    <DaysNet>30</DaysNet>
    <Standard>false</Standard>
    <ValidFrom>1997-01-01T00:00:00.000+01:00</ValidFrom>
  </TermsOfPayment>
</Supplier>

I want to read the ID of the Supplier and all child elements of TermsOfPayment and I wrote the code like this:

XNamespace ns = "http://www.example.com/xsd/2012/09";
var accountingunit = (from ele in XElement.Parse(textresult).Elements(ns + "TermsOfPayment")
                     select new node
                     {
                         TermsID = (string)ele.Element(ns + "ID"),
                         idvalue = (string)ele.Element(ns + "AccountingUnitId"),
                         shortname = (string)ele.Element(ns + "ShortName"),
                         name = (string)ele.Element(ns + "Name"),
                         Daysnet = (string)ele.Element(ns + "DaysNet"),
                         discountfirst = (int)ele.Element(ns + "DiscountPercentFirst"),
                         discountsecond = (int)ele.Element(ns + "DiscountPercentSecond"),
                         daysdiscountfirst = (string)ele.Element(ns + "DaysForDiscountFirst"),
                         daysdiscountsecond = (string)ele.Element(ns + "DaysForDiscountSecond"),
                         Termsstandard = (Boolean)ele.Element(ns + "Standard"),
                         ValidFrom = (string)ele.Element(ns + "ValidFrom"),
                         ValidTo = (string)ele.Element(ns + "ValidTo"),
                     });

But I am getting null if I try to read the accountingunit variable:

foreach ( unit in accountingunit)
{
}

Upvotes: 0

Views: 69

Answers (4)

Thomas Guibert
Thomas Guibert

Reputation: 1

For read/write on XML file, I use XMLSerializer. It's very simple :

You have to create a class :

public class Supplier
{
    public int ID {get;set;}
    public int AccountingUnitId {get;set;}
    public string ShortName {get;set;}
    public int AccountNumber {get;set;}
    public string BankAddress {get;set;}
    public string SupplierAddress {get;set;}
    public TermsOfPayment termPayment[] {get;set;}
}

With your class :

public class TermsOfPayment
{
    public int ID {get;set;}
    public string ShortName {get;set;}
    public string Name {get;set;}
    public int DaysNet {get;set;}
    public bool Standard {get;set;}
    public DateTime ValidFrom {get;set;}
}

For write :

Supplier SupplierTest = new Supplier();
XmlSerializer xs = new XmlSerializer(typeof(Supplier));
using (StreamWriter wr = new StreamWriter("supplier.xml"))
{
    xs.Serialize(wr, SupplierTest);
}

For read :

XmlSerializer xs = new XmlSerializer(typeof(Supplier));
using (StreamReader rd = new StreamReader("supplier.xml"))
{
    Supplier SupplierTest = xs.Deserialize(rd) as Supplier;
}

Upvotes: 0

StuartLC
StuartLC

Reputation: 107327

There's a couple of problems :

  • Supplier is in namespace xmlns="http://www.example.com/xsd/2012/09/, yet you are defineing XNamespace ns = "http://www.example.com/xsd/2012/09"; (note the missing trailing slash

  • Also, several of the elements, such as DaysForDiscountFirst, DiscountPercentFirst and DiscountPercentFirst are not present in both child TermsOfPayment nodes - you'll need to do some additional parsing here before you hard cast these in your projection to node.

Upvotes: 0

Cᴏʀʏ
Cᴏʀʏ

Reputation: 107576

Your namespace is wrong. You have:

XNamespace ns = "http://www.example.com/xsd/2012/09";

But the XML specifies:

http://www.example.com/xsd/2012/09/

You are missing the trailing /, which will prevent any elements from matching. Once that's corrected, you will also need to consider the root "Supplier" node; you don't have to get to it by name, but you could do:

from ele in XDocument.Parse(textresult).Root.Elements(ns + "TermsOfPayment")
            ^                           ^

Lastly, each TermsOfPayment node has different child elements. You will have to first check for their presence otherwise you will get further errors running your code.

Upvotes: 2

Richard
Richard

Reputation: 109100

XContainer.Elements(name) only looks for the named elements amongst its immediate children. But there is no TermsOfPayment that is a child of the document root.

Perhaps you wamt:

…XElement.Parse(textresult).Elements(ns+"Supplier").Elements(ns+"TermsOfPayment")

Upvotes: 1

Related Questions