我有这样的xml:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<supplyCrew xmlns="http://site.ddf.com">
<login>
<login>XXXX</login>
<password>XXXX</password>
</login>
<flightInformation>
<flights>
<item>
<arrivalDateTime>2010-11-08T22:48:00.000Z</arrivalDateTime>
<arrivingCity>ORD</arrivingCity>
<crewMembers>
<item>
<employeeId>020040</employeeId>
<isDepositor>Y</isDepositor>
<isTransmitter>N</isTransmitter>
</item>
<item>
<employeeId>09000</employeeId>
<isDepositor>N</isDepositor>
<isTransmitter>Y</isTransmitter>
</item>
</crewMembers>
</item>
<item>
<arrivalDateTime>2010-11-08T20:29:00.000Z</arrivalDateTime>
<arrivingCity>JFK</arrivingCity>
<crewMembers>
<item>
<employeeId>0538</employeeId>
<isDepositor>Y</isDepositor>
<isTransmitter>N</isTransmitter>
</item>
<item>
<employeeId>097790</employeeId>
<isDepositor>N</isDepositor>
<isTransmitter>Y</isTransmitter>
</item>
</crewMembers>
</item>
</flights>
</flightInformation>
</supplyCrew>
此代码仅获取第一个项“and”,然后生成异常'System.NullReferenceException'。
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Xml;
using System.Data.SqlClient;
using System.Data;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
XElement doc = XElement.Load("U:/Crew.xml");
XNamespace e = "http://schemas.xmlsoap.org/soap/envelope/";
XNamespace s = "http://site.ddf.com";
var flights = doc.Elements(e + "Body")
.Elements(s + "supplyCrew")
.Elements(s + "flightInformation")
.Elements(s + "flights")
.Elements(s + "item")
.Select(
flight_item => new
{
//Anonymous Type
arrivalDateTime = flight_item.Element(s + "arrivalDateTime").Value,
arrivingCity = flight_item.Element(s + "arrivingCity").Value,
crewmember = flight_item.Elements(s + "crewMembers").Elements(s + "item"),
}
);
int index = 1;
foreach (var flight_item in flights)
{
Console.Write('\n'+"New flight item:"+'\n');
Console.Write('\t'+flight_item.arrivalDateTime + '\n');
Console.Write('\t'+flight_item.arrivingCity + '\n');
foreach (var item in flight_item.crewmember)
{
var employeeId = item;//crewmember.Elements(s + "item").Elements("employeeId");
Console.Write("\t "+employeeId);
Console.Write('\n');
//index++;
}
}
我们的想法是为所有行获取item.arrivalDateTime和item.arrivingCity及其crewMembers.item.employeeId。但是,我不知道如何使用linq获取子节点...如果尝试employeeId = x.Element(s +“employeeId”),我们会发现异常。值....
结果应该是这样的:
2010-11-08T22:48:00.000Z; ORD; 020040
2010-11-08T22:48:00.000Z; ORD; 09000
2010-11-08T20:29:00.000Z; JFK; 0538
2010-11-08T20:29:00.000Z; JFK; 097790
答案 0 :(得分:3)
问题在于您使用Descendants
。您要求item
元素的所有flights
个后代 - 这意味着它将包含此内容:
<item>
<employeeId>020040</employeeId>
<isDepositor>Y</isDepositor>
<isTransmitter>N</isTransmitter>
</item>
显然没有arrivalDateTime
元素,因此存在问题。
在示例代码中替换Descendants
到Elements
的每次调用都可以解决问题......如果实际文档没有所有预期的数据,您仍然会失败。
答案 1 :(得分:0)
<强>解决强>
我们只需要替换那个foreach:
foreach (var flight_item in l_flights)
{
Console.Write('\n'+"New flight item:"+'\n');
Console.Write('\t'+flight_item.arrivalDateTime + '\n');
Console.Write('\t'+flight_item.arrivingCity + '\n');
foreach (var item in flight_item.crewmember)
{
var employeeId = item.Element(s + "employeeId").Value;
var isDepositor = item.Element(s + "isDepositor").Value;
var isTransmitter = item.Element(s + "isTransmitter").Value;
Console.Write("\t " + employeeId + "\n");
Console.Write("\t " + isDepositor + "\n");
Console.Write("\t " + isTransmitter + "\n");
}
}
谢谢你们......