简体   繁体   English

与XML名称空间(linq)纠缠...在这里我做错了什么?

[英]struggling with XML namespaces (linq)… what am I doing wrong here?

Trying to parse some XML but apparently this is too much for a lazy sunday afternoon, 试图解析一些XML,但显然对于一个懒惰的星期日下午来说,这太过分了,

this is my code: (I Tried the XPathDocument and XmlDocument approach too but this also failed miserably) 这是我的代码:(我也尝试过XPathDocument和XmlDocument方法,但这也不幸失败了)

 XmlDocument xmlDoc = new XmlDocument();
 xmlDoc.LoadXml(postData);
 XDocument xDoc = XDocument.Load(new XmlNodeReader(xmlDoc)); 
 XNamespace soapEnv = "http://schemas.xmlsoap.org/soap/envelope/";
 XElement xEnv = xDoc.Descendants(soapEnv + "Envelope").First();
 XElement xBody = xEnv.Descendants(soapEnv + "Body").First();
 XElement xReadReply = xBody.Descendants("ReadReplyReq").First();

The last line fails with the exception: no elements in this collection however if I change this last line into: 最后一行失败,但有一个例外:该集合中没有元素,但是如果我将最后一行更改为:

 XElement xReadReply = xBody.Descendants().First();

it returns the first node which in fact is the "ReadReplyReq" node. 它返回实际上是“ ReadReplyReq”节点的第一个节点。

Having finally gotten these Namespaces working, it now fails on the first node without a namepace... ooh bitter irony ;^) 终于使这些命名空间正常工作之后,它现在在没有命名空间的情况下在第一个节点上失败了。

This is the XML I'm trying to parse: 这是我要解析的XML:

 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
      <SOAP-ENV:Header>
           <TransactionID xmlns="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-2" SOAP-ENV:actor="" SOAP-ENV:mustUnderstand="1">12345678</TransactionID>
      </SOAP-ENV:Header>
      <SOAP-ENV:Body>
           <ReadReplyReq xmlns="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-2">
                <MMStatus>Read</MMStatus>
                <TimeStamp>2007-12-13T14:05:27+01:00</TimeStamp>
                <MessageID>54321</MessageID>
                <Sender>
                     <ShortCode>+12345</ShortCode>
                </Sender>
                <Recipient>
                     <Number>+12345</Number>
                </Recipient>
                <StatusText>Message has been read</StatusText>
                <MM7Version>5.3.0</MM7Version>
           </ReadReplyReq>
       </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

what last step am I missing here? 我在这里错过了最后一步吗?

ps and why can't the XPath not just be something more intuitive like: "//SOAP-ENV:Envelope/SOAP-ENV:Body/ReadReplyReq/MMStatus", instead of all these crazy hoops one has to jump through. ps以及为什么XPath不能像这样更直观:“ // SOAP-ENV:Envelope / SOAP-ENV:Body / ReadReplyReq / MMStatus”,而不是所有这些令人讨厌的篮球。

I am guessing what you want is to add a namespace manager so you can XPath select on prefixed nodes? 我猜您想要添加一个名称空间管理器,以便您可以在前缀节点上进行XPath选择吗?

If so then something like: 如果是这样,则类似:

var doc = new XmlDocument();

doc.LoadXml( postData );
var ns = new XmlNamespaceManager( doc.NameTable );
ns.AddNamespace( "SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/" );
ns.AddNamespace( "def", "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-2" );
XmlNode list = doc.SelectSingleNode( "//SOAP-ENV:Envelope/SOAP-ENV:Body/def:ReadReplyReq/def:MMStatus", ns );

Is probably what you want. 可能就是您想要的。

You don't need XPath you just need a namespace for the xReadReply element. 您不需要XPath,而只需要xReadReply元素的名称空间。 Declare the namespace just like you did for the soap elements and use it when searching for that element. 就像您对soap元素所做的那样声明名称空间,并在搜索该元素时使用它。

XNamespace transNS = "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-2";

XElement xReadReply = xBody.Descendants( transNS + "ReadReplyReq" ).First();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM