Linq to XML - 获取属性和元素
Linq to XML - Get attribute and elements
鉴于此 XML,我如何获取每个 outageEvent 的数据,包括属性和元素?
最后,我需要将这些数据移动到数据库中,但这是第一步。
对于具有属性 ObjectID
的每个 outageEvent,然后是 outageEvent 中的元素,所需的结束格式是 'row'。
outageEvent
-------------
ObjectID
Comment
objectName
...etc.
此时不需要获取 ExtensionList 子级等 outageEvent 的孙级。
到目前为止,我正在使用 Linq 查询 XML。我能够查询并获取 objectID。另外,我可以查询以获取所有元素。试图将两者结合起来给我带来了问题。有一段时间没有用过任何 C#,所以这是 99% 的问题。
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<OutageEventChangedNotification xmlns="http://www.multispeak.org/Version_4.1_Release">
<oEvents>
<outageEvent objectID="2021-10-16-0002">
<comments>Test outage 2</comments>
<extensionsList>
<extensionsItem>
<extName>primaryCrew</extName>
<extValue>Primary Crew Name</extValue>
<extType>string</extType>
</extensionsItem>
</extensionsList>
<objectName>Outage Name</objectName>
<!-- more elements -->
</outageEvent>
<outageEvent objectID="2021-10-16-0001">
<comments>Test outage 1</comments>
<!-- more elements -->
</outageEvent>
</oEvents>
</OutageEventChangedNotification>
</soap:Body>
</soap:Envelope>
C#代码:
XElement outages = XElement.Parse(requestBody);
XNamespace oecn = "http://www.multispeak.org/Version_4.1_Release";
//This works
IEnumerable<string> outageIDs = from outage in outages.Descendants(oecn + "outageEvent")
select (string) outage.Attribute("objectID");
foreach (string outageID in outageIDs)
{
Console.WriteLine($"IENUMERABLE: {outageID}");
}
//This works
IEnumerable<string> outageProperties = from outage in outages.Descendants(oecn + "outageEvent")
select (string)outage;
foreach (string outageProperty in outageProperties)
{
Console.WriteLine($"IENUMERABLE: {outageProperty} \r\n");
}
//This Doesn't
var alloutages = from outage in outages.Descendants(oecn + "outageEvent")
select new /*Error Here*/
{
outageID = outage.Attribute("objectID").Value,
comments = outage.Element("comments").Value
};
foreach (var outage in alloutages)
{
Console.WriteLine($"OUTPUT: {outage.outageID}");
}
输出:
Hello World!
IENUMERABLE: 2021-10-16-0002
IENUMERABLE: 2021-10-16-0001
IENUMERABLE: Test outage 2primaryCrewPrimary Crew NamestringOutage Name0032.427326-99.788595TRANSFORMER1District9TRANSFORMER1TransformerA10FeederNameAssumed2015-01-01T10:00:00Z2015-01-01T10:30:00Z2015-01-01T11:00:00ZCrew1Crew21010Contractor44
IENUMERABLE: Test outage 1primaryCrewPrimary Crew NamestringOutage Name0032.427326-99.788595TRANSFORMER1District9TRANSFORMER1TransformerA10FeederNameAssumed2015-01-01T10:00:00Z2015-01-01T10:30:00Z2015-01-01T11:00:00ZCrew11010Contractor44
var = alloutages 部分出错,突出显示 'select new' 块。
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=ParseXMLWithLinq
StackTrace:
at XMLParse.Program.<>c.<Main>b__0_2(XElement outage) in
System.Xml.Linq.XContainer.Element(...) returned null.
分配的内容如下所示:
<outageEvent objectID="2021-10-16-0002" xmlns="http://www.multispeak.org/Version_4.1_Release">
<comments>Test outage 2</comments>
<extensionsList>
<extensionsItem>
<extName>primaryCrew</extName>
<extValue>Primary Crew Name</extValue>
<extType>string</extType>
...
</outageEvent>
异常的原因是 outageEvent
中的 comments
元素与 outageEvent
处于相同的命名空间中,因此在 http://www.multispeak.org/Version_4.1_Release
中。所以代替:
select new /*Error Here*/
{
outageID = outage.Attribute("objectID").Value,
comments = outage.Element("comments").Value
};
您需要做的事情:
select new /*Error Here*/
{
outageID = outage.Attribute("objectID").Value,
// use namespace you already have here
comments = outage.Element(oecn + "comments").Value
};
另一种方法是按本地名称过滤元素:
select new /*Error Here*/
{
outageID = outage.Attribute("objectID").Value,
comments = outage.Elements().First(c => c.Name.LocalName == "comments").Value
};
鉴于此 XML,我如何获取每个 outageEvent 的数据,包括属性和元素?
最后,我需要将这些数据移动到数据库中,但这是第一步。
对于具有属性 ObjectID
的每个 outageEvent,然后是 outageEvent 中的元素,所需的结束格式是 'row'。
outageEvent
-------------
ObjectID
Comment
objectName
...etc.
此时不需要获取 ExtensionList 子级等 outageEvent 的孙级。
到目前为止,我正在使用 Linq 查询 XML。我能够查询并获取 objectID。另外,我可以查询以获取所有元素。试图将两者结合起来给我带来了问题。有一段时间没有用过任何 C#,所以这是 99% 的问题。
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
</soap:Header>
<soap:Body>
<OutageEventChangedNotification xmlns="http://www.multispeak.org/Version_4.1_Release">
<oEvents>
<outageEvent objectID="2021-10-16-0002">
<comments>Test outage 2</comments>
<extensionsList>
<extensionsItem>
<extName>primaryCrew</extName>
<extValue>Primary Crew Name</extValue>
<extType>string</extType>
</extensionsItem>
</extensionsList>
<objectName>Outage Name</objectName>
<!-- more elements -->
</outageEvent>
<outageEvent objectID="2021-10-16-0001">
<comments>Test outage 1</comments>
<!-- more elements -->
</outageEvent>
</oEvents>
</OutageEventChangedNotification>
</soap:Body>
</soap:Envelope>
C#代码:
XElement outages = XElement.Parse(requestBody);
XNamespace oecn = "http://www.multispeak.org/Version_4.1_Release";
//This works
IEnumerable<string> outageIDs = from outage in outages.Descendants(oecn + "outageEvent")
select (string) outage.Attribute("objectID");
foreach (string outageID in outageIDs)
{
Console.WriteLine($"IENUMERABLE: {outageID}");
}
//This works
IEnumerable<string> outageProperties = from outage in outages.Descendants(oecn + "outageEvent")
select (string)outage;
foreach (string outageProperty in outageProperties)
{
Console.WriteLine($"IENUMERABLE: {outageProperty} \r\n");
}
//This Doesn't
var alloutages = from outage in outages.Descendants(oecn + "outageEvent")
select new /*Error Here*/
{
outageID = outage.Attribute("objectID").Value,
comments = outage.Element("comments").Value
};
foreach (var outage in alloutages)
{
Console.WriteLine($"OUTPUT: {outage.outageID}");
}
输出:
Hello World!
IENUMERABLE: 2021-10-16-0002
IENUMERABLE: 2021-10-16-0001
IENUMERABLE: Test outage 2primaryCrewPrimary Crew NamestringOutage Name0032.427326-99.788595TRANSFORMER1District9TRANSFORMER1TransformerA10FeederNameAssumed2015-01-01T10:00:00Z2015-01-01T10:30:00Z2015-01-01T11:00:00ZCrew1Crew21010Contractor44
IENUMERABLE: Test outage 1primaryCrewPrimary Crew NamestringOutage Name0032.427326-99.788595TRANSFORMER1District9TRANSFORMER1TransformerA10FeederNameAssumed2015-01-01T10:00:00Z2015-01-01T10:30:00Z2015-01-01T11:00:00ZCrew11010Contractor44
var = alloutages 部分出错,突出显示 'select new' 块。
System.NullReferenceException
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=ParseXMLWithLinq
StackTrace:
at XMLParse.Program.<>c.<Main>b__0_2(XElement outage) in
System.Xml.Linq.XContainer.Element(...) returned null.
分配的内容如下所示:
<outageEvent objectID="2021-10-16-0002" xmlns="http://www.multispeak.org/Version_4.1_Release">
<comments>Test outage 2</comments>
<extensionsList>
<extensionsItem>
<extName>primaryCrew</extName>
<extValue>Primary Crew Name</extValue>
<extType>string</extType>
...
</outageEvent>
异常的原因是 outageEvent
中的 comments
元素与 outageEvent
处于相同的命名空间中,因此在 http://www.multispeak.org/Version_4.1_Release
中。所以代替:
select new /*Error Here*/
{
outageID = outage.Attribute("objectID").Value,
comments = outage.Element("comments").Value
};
您需要做的事情:
select new /*Error Here*/
{
outageID = outage.Attribute("objectID").Value,
// use namespace you already have here
comments = outage.Element(oecn + "comments").Value
};
另一种方法是按本地名称过滤元素:
select new /*Error Here*/
{
outageID = outage.Attribute("objectID").Value,
comments = outage.Elements().First(c => c.Name.LocalName == "comments").Value
};