如果元素具有 xmlns 属性,XDocument 和 Linq 返回 null

发布于 2024-11-06 03:49:59 字数 2054 浏览 0 评论 0原文

使用 XDocuments 和 Linq 的新手,请建议一个从 xml 字符串中的特定标记检索数据的解决方案:

如果我有来自 webservice 响应的 XML 字符串(为了方便起见,我格式化了 xml):

<?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">
  <soap:Body>
    <GetCashFlowReportResponse xmlns="http://tempuri.org/">
      <GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf>
    </GetCashFlowReportResponse>
  </soap:Body>
</soap:Envelope>

使用以下代码,我可以获取该值仅当 GetCashFlowReportResponse 标记没有 "xmlns" 属性时。不知道为什么?否则,它总是返回 null。

string inputString = "<?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\"><soap:Body><GetCashFlowReportResponse xmlns=\"http://tempuri.org/\"><GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf></GetCashFlowReportResponse></soap:Body></soap:Envelope>"    
XDocument xDoc = XDocument.Parse(inputString);
//XNamespace ns = "http://tempuri.org/";
XNamespace ns = XNamespace.Get("http://tempuri.org/");

var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
           select (string)c.Element("GetCashFlowReportPdf");

foreach (string val in data)
{
    Console.WriteLine(val);
}

我无法更改 Web 服务来删除该属性。是否有更好的方法来读取响应并将实际数据返回给用户(以更易读的形式)?

编辑: 解决方案:

XDocument xDoc = XDocument.Parse(inputString);
XNamespace ns = "http://tempuri.org/";

var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
           select (string)c.Element(ns + "GetCashFlowReportPdf");
foreach (string val in data)
{
   Console.WriteLine(val);
}

注意:即使所有子元素都没有名称空间属性,如果您将“ns”添加到元素中,代码也会起作用,因为我猜子元素会从父元素继承名称空间(请参阅SLAks 的回应)。

Newbie with XDocuments and Linq, please suggest a solution to retrieve the data from a particular tag in the xml string:

If I have a XML string from webservice response (I formatted xml for ease):

<?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">
  <soap:Body>
    <GetCashFlowReportResponse xmlns="http://tempuri.org/">
      <GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf>
    </GetCashFlowReportResponse>
  </soap:Body>
</soap:Envelope>

Using the following code, I can get the value only if GetCashFlowReportResponse tag doesn't have "xmlns" attribute. Not sure why? Otherwise, it always return null.

string inputString = "<?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\"><soap:Body><GetCashFlowReportResponse xmlns=\"http://tempuri.org/\"><GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf></GetCashFlowReportResponse></soap:Body></soap:Envelope>"    
XDocument xDoc = XDocument.Parse(inputString);
//XNamespace ns = "http://tempuri.org/";
XNamespace ns = XNamespace.Get("http://tempuri.org/");

var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
           select (string)c.Element("GetCashFlowReportPdf");

foreach (string val in data)
{
    Console.WriteLine(val);
}

I can't change the web service to remove that attribute. IS there a better way to read the response and get the actual data back to the user (in more readable form)?

Edited:
SOLUTION:

XDocument xDoc = XDocument.Parse(inputString);
XNamespace ns = "http://tempuri.org/";

var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
           select (string)c.Element(ns + "GetCashFlowReportPdf");
foreach (string val in data)
{
   Console.WriteLine(val);
}

Note: Even if all the child elements doesn't have the namespace attribute, the code will work if you add the "ns" to the element as I guess childs inherit the namespace from parent (see response from SLaks).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

又怨 2024-11-13 03:49:59

您需要包含名称空间:

XNamespace ns = "http://tempuri.org/";

xDoc.Descendants(ns + "GetCashFlowReportResponse")

You need to include the namespace:

XNamespace ns = "http://tempuri.org/";

xDoc.Descendants(ns + "GetCashFlowReportResponse")
_畞蕅 2024-11-13 03:49:59
XName qualifiedName = XName.Get("GetCashFlowReportResponse", 
    "http://tempuri.org/");

var data = from d in xDoc.Descendants(qualifiedName)
XName qualifiedName = XName.Get("GetCashFlowReportResponse", 
    "http://tempuri.org/");

var data = from d in xDoc.Descendants(qualifiedName)
离去的眼神 2024-11-13 03:49:59

只需使用限定名称来请求元素:

// create a XML namespace object
XNamespace ns = XNamespace.Get("http://tempuri.org/");

var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
           select (string)c.Element(ns + "GetCashFlowReportPdf");

请注意使用重载的 + 运算符,该运算符创建具有 XML 命名空间和本地名称字符串的 QName。

Just ask for the elements using the qualified names:

// create a XML namespace object
XNamespace ns = XNamespace.Get("http://tempuri.org/");

var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
           select (string)c.Element(ns + "GetCashFlowReportPdf");

Note the use of the overloaded + operator that creates a QName with a XML namespace and a local name string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文