无法使用 XDocument 从 XML 中提取子元素
Unable to extract child element from an XML using XDocument
以下是我试图从中提取子元素的 XML。
<?xml version="1.0" encoding="UTF8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header xmlns="http://SomeValue/SomeValue/2009/01/SomeValue.xsd">
<Session>
<SessionId>SomeValue</SessionId>
<SequenceNumber>1</SequenceNumber>
<SecurityToken>SomeValue</SecurityToken>
</Session>
</soap:Header>
<soap:Body>
<Security_AuthenticateReply xmlns="http://SomeValue/SomeValue">
<processStatus>
<statusCode>P</statusCode>
</processStatus>
</Security_AuthenticateReply>
</soap:Body>
</soap:Envelope>
public static string AssignSecurityToken(string response)
{
string Token = "";
XNamespace ns = "http://schemas.xmlsoap.org/soap/envelope/";
XElement xdoc = XElement.Parse(response);
XElement root = xdoc.Descendants(ns + "Header").First();
Token = root.Element("Session").Element("SecurityToken").Value;
Token = root.Descendants("Session").Descendants().Where(n => n.Name == "SecurityToken").FirstOrDefault().Value;
return Token;
}
我想提取元素安全令牌。
以下是我已经做过的事情:
尝试使用 post 中建议的方法提取元素
How to get value of child node from XDocument
另外post正在编写一些代码以供参考。这两个陈述都是
为 Token 变量赋值会抛出“对象未设置
一个对象的实例“异常。
提前致谢。
您需要考虑 Header
的命名空间。
public static string AssignSecurityToken(string response)
{
XNamespace ns1 = "http://schemas.xmlsoap.org/soap/envelope/";
XNamespace ns2 = "http://SomeValue/SomeValue/2009/01/SomeValue.xsd";
var envelope = XElement.Parse(response);
var header = envelope.Element(ns1 + "Header");
var session = header.Element(ns2 + "Session");
var security_token = session.Element(ns2 + "SecurityToken");
return security_token.Value;
}
其实你可以继续打电话
return XElement.Parse(response).Descendants()
.First(x => x.Name.LocalName == "SecurityToken").Value;
仅对于 this 响应,仅解析字符串并提取元素是有意义的。
此响应使用两个名称空间,一个用于 SOAP headers,另一个用于 Amadeus 登录响应。您需要第二个来检索令牌:
//SOAP-only namespace
XNamespace soap = "http://schemas.xmlsoap.org/soap/envelope/";
//Default namespace
XNamespace ns = "http://SomeValue/SomeValue/2009/01/SomeValue.xsd";
var response=XElement.Parse(xml);
var token=response.Descendants(ns+"SecurityToken").First().Value;
其他 Amadeus 响应非常庞大,XDocument 不会比使用 WCF 和反序列化为强类型好多少(如果有的话)objects。 XDocument 反序列化整个 XML 响应,与 DataContractSerializer 相同。不过,您得到的不是 strongly-typed 的 objects 集,而是必须映射到其他内容的 XElements。
如果您想通过只读取部分来减少内存消耗,您将不得不使用 XmlReader 并从响应流中一个接一个地读取 XML 标记。还有很多工作要做。
另一个有趣的事情是 Amadeus 响应使用 多个 命名空间。此响应仅使用 2。其他响应(例如搜索)使用更多。
您可以考虑使用 System.Xml.XmlDocument
和 System.Xml.XPath.XPathNavigator
,它们真的很容易使用。
I wrote a simple example for you (supporting UTF-8 encoding):
System.Xml.XmlDocument someXmlFile = new System.Xml.XmlDocument();
string xmlPath= @"YOUR_XML_FULL_PATH";
string innerNodeToExtract= @"/Session/SecurityToken";
try
{
// Loading xml file with utf-8 encoding:
string xmlFileStr= Systm.IO.File.ReadAllText(xmlPath, System.Text.Encoding.UTF8);
// Creating the XPathNavigator:
System.Xml.XPath.XPathNavigator xmlNavigator= someXmlFile.CreateNavigator();
// Getting the inner value as string:
string value = xmlNavigator.SelectSingleNode(innerNodeToExtract).Value;
// some code...
}
catch(Exception)
{
// Handle failures
}
Please notice that you can also:
Extract inner values using "@" key.
Move to the child using xmlNavigator.MoveToNext()
.
And many other things that you can read here.
以下是我试图从中提取子元素的 XML。
<?xml version="1.0" encoding="UTF8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header xmlns="http://SomeValue/SomeValue/2009/01/SomeValue.xsd">
<Session>
<SessionId>SomeValue</SessionId>
<SequenceNumber>1</SequenceNumber>
<SecurityToken>SomeValue</SecurityToken>
</Session>
</soap:Header>
<soap:Body>
<Security_AuthenticateReply xmlns="http://SomeValue/SomeValue">
<processStatus>
<statusCode>P</statusCode>
</processStatus>
</Security_AuthenticateReply>
</soap:Body>
</soap:Envelope>
public static string AssignSecurityToken(string response)
{
string Token = "";
XNamespace ns = "http://schemas.xmlsoap.org/soap/envelope/";
XElement xdoc = XElement.Parse(response);
XElement root = xdoc.Descendants(ns + "Header").First();
Token = root.Element("Session").Element("SecurityToken").Value;
Token = root.Descendants("Session").Descendants().Where(n => n.Name == "SecurityToken").FirstOrDefault().Value;
return Token;
}
我想提取元素安全令牌。
以下是我已经做过的事情:
尝试使用 post 中建议的方法提取元素 How to get value of child node from XDocument
另外post正在编写一些代码以供参考。这两个陈述都是 为 Token 变量赋值会抛出“对象未设置 一个对象的实例“异常。
提前致谢。
您需要考虑 Header
的命名空间。
public static string AssignSecurityToken(string response)
{
XNamespace ns1 = "http://schemas.xmlsoap.org/soap/envelope/";
XNamespace ns2 = "http://SomeValue/SomeValue/2009/01/SomeValue.xsd";
var envelope = XElement.Parse(response);
var header = envelope.Element(ns1 + "Header");
var session = header.Element(ns2 + "Session");
var security_token = session.Element(ns2 + "SecurityToken");
return security_token.Value;
}
其实你可以继续打电话
return XElement.Parse(response).Descendants()
.First(x => x.Name.LocalName == "SecurityToken").Value;
仅对于 this 响应,仅解析字符串并提取元素是有意义的。 此响应使用两个名称空间,一个用于 SOAP headers,另一个用于 Amadeus 登录响应。您需要第二个来检索令牌:
//SOAP-only namespace
XNamespace soap = "http://schemas.xmlsoap.org/soap/envelope/";
//Default namespace
XNamespace ns = "http://SomeValue/SomeValue/2009/01/SomeValue.xsd";
var response=XElement.Parse(xml);
var token=response.Descendants(ns+"SecurityToken").First().Value;
其他 Amadeus 响应非常庞大,XDocument 不会比使用 WCF 和反序列化为强类型好多少(如果有的话)objects。 XDocument 反序列化整个 XML 响应,与 DataContractSerializer 相同。不过,您得到的不是 strongly-typed 的 objects 集,而是必须映射到其他内容的 XElements。
如果您想通过只读取部分来减少内存消耗,您将不得不使用 XmlReader 并从响应流中一个接一个地读取 XML 标记。还有很多工作要做。
另一个有趣的事情是 Amadeus 响应使用 多个 命名空间。此响应仅使用 2。其他响应(例如搜索)使用更多。
您可以考虑使用 System.Xml.XmlDocument
和 System.Xml.XPath.XPathNavigator
,它们真的很容易使用。
I wrote a simple example for you (supporting UTF-8 encoding):
System.Xml.XmlDocument someXmlFile = new System.Xml.XmlDocument();
string xmlPath= @"YOUR_XML_FULL_PATH";
string innerNodeToExtract= @"/Session/SecurityToken";
try
{
// Loading xml file with utf-8 encoding:
string xmlFileStr= Systm.IO.File.ReadAllText(xmlPath, System.Text.Encoding.UTF8);
// Creating the XPathNavigator:
System.Xml.XPath.XPathNavigator xmlNavigator= someXmlFile.CreateNavigator();
// Getting the inner value as string:
string value = xmlNavigator.SelectSingleNode(innerNodeToExtract).Value;
// some code...
}
catch(Exception)
{
// Handle failures
}
Please notice that you can also:
Extract inner values using "@" key.
Move to the child using
xmlNavigator.MoveToNext()
.And many other things that you can read here.