【问题标题】:How can I grab user name from XML via LINQ to XML?如何通过 LINQ to XML 从 XML 中获取用户名?
【发布时间】:2010-09-07 16:16:49
【问题描述】:

我需要记录正在使用 ASP.NET Web 服务的用户名。为此,我创建了一个 SoapExtension,它捕获传入的 Soap 信封并将其转换为 XDocument。问题是我对 LINQ to XML 一无所知,而且我查看过的示例似乎不太适用于 SOAP 信封。

SOAP 消息如下所示:

 <?xml version="1.0" encoding="utf-8"?>
 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
   <soap:Header>
     <wsa:Action>http://www.company.net/2009/09/17/wriapp/GetConfigInfo</wsa:Action>
     <wsa:MessageID>urn:uuid:da599d3d-1df5-4460-8987-8ccd75b87cfe</wsa:MessageID>
     <wsa:ReplyTo><wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address></wsa:ReplyTo>
     <wsa:To>urn:Company:Wri:Tracking:1.0</wsa:To>
     <wsse:Security soap:mustUnderstand="1">
       <wsu:Timestamp wsu:Id="Timestamp-efb2ad77-7822-43d9-86d6-0cbfbf0ed262">
           <wsu:Created>2010-09-07T13:31:20Z</wsu:Created>
           <wsu:Expires>2010-09-07T13:36:20Z</wsu:Expires>
       </wsu:Timestamp>
       <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-c51f6c78-555b-420c-ba79-402d75f24d5e">
         <wsse:Username>user@mycompany.net</wsse:Username>
         <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password1</wsse:Password>
         <wsse:Nonce>xO+f8fJgh8zzxPi6JJMUag==</wsse:Nonce>
         <wsu:Created>2010-09-07T13:31:20Z</wsu:Created>
       </wsse:UsernameToken>
     </wsse:Security>
   </soap:Header>
   <soap:Body>
     <GetConfigInfo xmlns="http://www.company.net/2009/09/17/wriapp" />
   </soap:Body>
 </soap:Envelope>

我只需要用户名元素的内容。

我试过了……

 var xdoc = XDocument.Parse(xml, LoadOptions.None);
 var userName = from item in xdoc.Descendants("UsernameToken")
                select new
                {
                    UserName = item.Element("UserName")
                };

...但没有得到任何结果。

当我尝试使用“wsse:UsernameToken”和“wsse:Username”时,我得到一个异常,指出冒号不合法。

有关如何获取此信息的任何提示?

(我知道我可能只是对名称进行正则表达式,但如果我需要在将来某个时候获取其他数据,那么我认为这样会更有效。)

【问题讨论】:

    标签: c# asp.net xml web-services soap


    【解决方案1】:

    冒号前面的部分是命名空间,知道这一点我从一个类似的问题中找到了这个答案。

    Linq to XML with Namespace

    【讨论】:

    • 几个人有一个有用的答案,但这是第一个(根据“最古老”的排序),所以它得到了答案。他们都得到了 +1。
    【解决方案2】:

    您需要创建一个命名空间并使用它。它高度违反直觉,但这就是它的工作原理:

    XNamespace ns = "http://schemas.xmlsoap.org/soap/envelope/";
    from item in xdoc.Descendants(ns + "UsernameToken")
    ...etc...
    

    ...对于任何有前缀的项目,您都必须这样做。

    我认为您也可以使用花括号 ({}) 作为 URI 的包装器,如下所示:

    来自 xdoc.Descendants("{http://schemas.xmlsoap.org/soap/envelope/}UsernameToken") 中的项目

    但我从未尝试过。

    More details here.

    【讨论】:

      【解决方案3】:

      这取决于那些 xml 元素的命名空间。您需要将其添加到您的查询中。我不想尝试这个,而是类似以下内容:

      XNamespace wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
      
       var xdoc = XDocument.Parse(xml, LoadOptions.None);
       var userName = from item in xdoc.Descendants(wsu + "UsernameToken")
                      select new
                      {
                          UserName = item.Element(wsu + "UserName")
                      };
      

      有关 LINQ to XML 中的命名空间的更多信息:http://msdn.microsoft.com/en-us/library/bb387069.aspx

      【讨论】:

        【解决方案4】:

        您必须在 LINQ 中包含整个命名空间:

        XNamespace wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
        
        var xdoc = XDocument.Parse(xml, LoadOptions.None);
        var userName = from item in xdoc.Descendants(wsse + "UsernameToken")
                        select new
                        {
                            UserName = item.Element(wsse + "UserName")
                        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-21
          • 1970-01-01
          • 1970-01-01
          • 2011-04-14
          • 1970-01-01
          • 2013-11-13
          相关资源
          最近更新 更多