[英]Parsing SOAP response in C#
我是新的 C#。我發出 SOAP 請求,在 SOAP 響應中,我需要訪問重復節點“ABC”。 這就是我的 SOAP 響應的樣子:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<work:WorkContext xmlns:work="http://example.com/soap/workarea/">sdhjasdajsdhj=</work:WorkContext>
</env:Header>
<env:Body>
<ReadABCResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.xyz.com/abc/a6/AB/XYZ/V1">
<ABC xmlns="http://xmlns.xyz.example/abc/a6/AB/XYZ/V1">
<asd xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1" xsi:nil="true"/>
<xyz xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1" xsi:nil="true"/>
</ABC>
<ABC xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1">
<asd xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1" xsi:nil="true"/>
<xyz xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1" xsi:nil="true"/>
</ABC>
</ReadABCResponse>
</env:Body>
</env:Envelope>
我的代碼如下:
XmlDocument responseDoc = new XmlDocument();
responseDoc.LoadXml(responseString); //responseString is set to above SOAP response.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(responseDoc.NameTable);
nsmgr.AddNamespace("env", "http://schemas.xmlsoap.org/soap/envelope/");
nsmgr.AddNamespace("work", "http://example.com/soap/workarea/");
nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
nsmgr.AddNamespace("", "http://xmlns.example.com/abc/a6/AB/XYZ/V1");
XmlNodeList lst = responseDoc.SelectNodes("/env:Envelope/env:Body/ReadABCResponse/ABC", nsmgr);
Console.WriteLine("Count " + lst.Count);
// and then iterate over the repeating ABC nodes to do some work.
然而,Count 的值始終打印為 0。我在“SelectNodes”方法中嘗試了 xpath 路徑的不同組合,包括“//ABC”——我認為它應該給我所有重復的“ABC”節點,但它沒有。
我的代碼有什么問題。 請有人突出顯示並幫助我!
我在這個網站上四處張望,但無法弄清楚這段代碼有什么問題。
下面展示如何使用XDocument從XML中讀取數據。
測試.xml :
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
<work:WorkContext xmlns:work="http://example.com/soap/workarea/">sdhjasdajsdhj=</work:WorkContext>
</env:Header>
<env:Body>
<ReadABCResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.xyz.com/abc/a6/AB/XYZ/V1">
<ABC xmlns="http://xmlns.xyz.example/abc/a6/AB/XYZ/V1">
<asd xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1" xsi:nil="true">asd data 1</asd>
<xyz xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1" xsi:nil="true">xyz data 1</xyz>
</ABC>
<ABC xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1">
<asd xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1" xsi:nil="true">asd data 2</asd>
<xyz xmlns="http://xmlns.example.com/abc/a6/AB/XYZ/V1" xsi:nil="true">xyz data 2</xyz>
</ABC>
</ReadABCResponse>
</env:Body>
</env:Envelope>
添加以下使用語句:
using System.Xml;
using System.Xml.Linq;
using System.Diagnostics;
創建一個class (名稱:ABC.cs)
public class ABC
{
public string Asd { get; set; }
public string Xyz { get; set; }
}
選項 1 :
private void GetABC()
{
//ToDo: replace with your XML data
string xmlText = "your XML data...";
//parse XML
XDocument doc = XDocument.Parse(xmlText);
//create new instance
List<ABC> abcs = new List<ABC>();
foreach (XElement elem in doc.Descendants().Where(x => x.Name.LocalName == "ABC"))
{
//create new instance
ABC abc = new ABC();
foreach (XElement elemChild in elem.Descendants())
{
//Debug.WriteLine($"{elemChild.Name}: '{elemChild.Value?.ToString()}'");
if (elemChild.Name.LocalName == "asd")
abc.Asd = elemChild.Value?.ToString();
else if (elemChild.Name.LocalName == "xyz")
abc.Xyz = elemChild.Value?.ToString();
}
//add to List
abcs.Add(abc);
}
foreach (ABC abc in abcs)
{
Debug.WriteLine($"ABC: '{abc.Asd}' XYZ: '{abc.Xyz}'");
}
}
選項 2 :
private void GetABC()
{
//ToDo: replace with your XML data
string xmlText = "your XML data...";
//parse XML
XDocument doc = XDocument.Parse(xmlText);
//get namespace
XNamespace nsABC = doc.Descendants().Where(x => x.Name.LocalName == "ABC").FirstOrDefault().GetDefaultNamespace();
List<ABC> abcs = doc.Descendants().Where(x => x.Name.LocalName == "ABC").Select(x2 => new ABC()
{
Asd = (string)x2.Element(nsABC + "asd"),
Xyz = (string)x2.Element(nsABC + "xyz")
}).ToList();
foreach (ABC abc in abcs)
{
Debug.WriteLine($"ABC: '{abc.Asd}' XYZ: '{abc.Xyz}'");
}
}
資源:
您也可以這樣做:復制 xml 並使用“選擇性粘貼”->“將 Xml 粘貼為類”將其粘貼到 Visual Studio 中。 現在您將擁有一個信封 class,您可以反序列化 xml,如本例所示: https://learn.microsoft.com/en-us/do.net/api/system.xml.serialization.xmlserializer.deserialize?view。凈 7.0 。 Soap 消息可能非常復雜,使用可以修改並在需要時最終序列化的對象會更容易。
感謝您的回復,但我設法解決了它。 在 namsspace 管理器中,我做了以下更改
nsmgr.AddNamespace("x", "http://xmlns.example.com/abc/a6/AB/XYZ/V1");
在列出 ABC 節點時,我做了以下更改,即在 ABC 前加上 x:
XmlNodeList lst = responseDoc.SelectNodes("//x:ABC", nsmgr);
Rest 的代碼保持原樣,現在我可以遍歷所有 ABC 節點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.