Linq XML 读取器无法正常工作

本文关键字:常工作 工作 XML 读取 Linq | 更新日期: 2023-09-27 18:33:51

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

但是如果我尝试读取accountingunit变量,我会null

foreach ( unit in accountingunit)
{
}

Linq XML 读取器无法正常工作

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

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

但 XML 指定:

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

您缺少尾随/,这将阻止任何元素匹配。更正后,您还需要考虑根"供应商"节点;您不必按名称访问它,但您可以执行以下操作:

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

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

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

也许你徘徊:

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

有几个问题:

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

  • 此外,一些元素(例如 DaysForDiscountFirstDiscountPercentFirstDiscountPercentFirst)在两个子节点TermsOfPayment节点中都不存在 - 在将这些元素硬投射到node之前,您需要在此处进行一些额外的解析。

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