Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 正在与XML名称空间(linq)斗争。。。我做错了什么?_C#_.net_Xml_Soap_Linq To Xml - Fatal编程技术网

C# 正在与XML名称空间(linq)斗争。。。我做错了什么?

C# 正在与XML名称空间(linq)斗争。。。我做错了什么?,c#,.net,xml,soap,linq-to-xml,C#,.net,Xml,Soap,Linq To Xml,试图解析一些XML,但显然这对于一个懒散的周日下午来说太多了 这是我的代码:(我也尝试了XPathDocument和XmlDocument方法,但也失败得很惨) 最后一行失败,出现异常:此集合中没有元素 但是,如果我将最后一行更改为: XElement xReadReply = xBody.Descendants().First(); 它返回第一个节点,实际上是“ReadReplyReq”节点 终于让这些名称空间工作起来了,现在它在没有名称空间的第一个节点上失败了。。。哦,辛辣的讽刺;^)

试图解析一些XML,但显然这对于一个懒散的周日下午来说太多了

这是我的代码:(我也尝试了XPathDocument和XmlDocument方法,但也失败得很惨)

最后一行失败,出现异常:此集合中没有元素 但是,如果我将最后一行更改为:

 XElement xReadReply = xBody.Descendants().First();
它返回第一个节点,实际上是“ReadReplyReq”节点

终于让这些名称空间工作起来了,现在它在没有名称空间的第一个节点上失败了。。。哦,辛辣的讽刺;^)

这是我试图解析的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>

12345678
阅读
2007-12-13T14:05:27+01:00
54321
+12345
+12345
消息已被阅读
5.3.0
我在这里错过了最后一步是什么


p、 为什么XPath不能更直观一些,比如:“//SOAP-ENV:Envelope/SOAP-ENV:Body/ReadReplyReq/MMStatus”,而不是必须跳过所有这些疯狂的环。

我猜您想要的是添加一个名称空间管理器,以便可以在前缀节点上选择XPath

如果是这样的话,那么类似于:

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 );

这可能就是您想要的。

您不需要XPath,只需要xReadReply元素的名称空间。像对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();

def只是放在名称空间管理器中的一个伪前缀,用于标识body子节点上使用的默认名称空间。我已将您的答案转换为我的linq代码,它确实有效。默认名称空间起到了作用。您怎么能看到您拥有的url确实是默认名称空间所需的值?在xml中,我只在某个地方看到了属性:xmlns(xml名称空间?)这是一直使用的某个默认标记吗?呃,我想您可能需要阅读更多关于xml名称空间支持的内容:)如果指定xmlns=它将把该名称空间URL应用于所有没有前缀的子节点。因此,由于MMStatus处于ReadReplyRequest下,它占用了上面的默认设置。我以前从未遇到过名称空间…从未需要它。我已经很高兴,通过大量的谷歌搜索,我已经尽了最大努力;^)我真的认为xml已经有点过头了。感谢上帝的帮助;^)
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();