Linq XML阅读器无法正常工作

时间:2014-12-09 14:53:02

标签: c# linq-to-xml

我的XML是这样的:

<?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>

我想阅读供应商的ID以及TermsOfPayment的所有子元素,我写了这样的代码:

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"),
                     });

但是如果我尝试阅读null变量,我将获得accountingunit

foreach ( unit in accountingunit)
{
}

4 个答案:

答案 0 :(得分:2)

您的命名空间错误。你有:

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

但XML指定:

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

您缺少尾随/,这会阻止任何元素匹配。一旦纠正了,您还需要考虑根源&#34;供应商&#34;节点;你不必通过名字来达到它,但你可以这样做:

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

最后,每个TermsOfPayment节点都有不同的子元素。您必须首先检查它们的存在,否则您将在运行代码时遇到进一步的错误。

答案 1 :(得分:1)

XContainer.Elements(name)仅查找其直接子项中的命名元素。但是没有TermsOfPayment是文档根目录的子代。

也许你这么说:

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

答案 2 :(得分:0)

有几个问题:

  • 供应商位于名称空间xmlns="http://www.example.com/xsd/2012/09/中,但您正在定义XNamespace ns = "http://www.example.com/xsd/2012/09";(请注意缺少的斜杠

  • 此外,DaysForDiscountFirstDiscountPercentFirstDiscountPercentFirst等多个元素在两个子节点TermsOfPayment中都不存在 - 您需要在将投影中的这些内容强制投射到node之前,请先进行一些额外的解析。

答案 3 :(得分:0)

对于XML文件的读/写,我使用XMLSerializer。这很简单:

你必须创建一个类:

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;}
}

上课:

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;}
}

写作:

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

阅读:

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