如何正确处理此XML响应(SOAP:Envelope)以获取至少一个DataView / DataTable?

时间:2015-10-01 12:33:56

标签: c# xml soap

我再次遇到一个XML文档的问题,我收到的是Web请求(HP Service Manager)的响应。

这是XML响应:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<RetrieveSDToDoListResponse 
message="Success" returnCode="0" 
schemaRevisionDate="2015-09-24" 
schemaRevisionLevel="0" status="SUCCESS" 
xmlns="http://schemas.hp.com/SM/7" 
xmlns:cmn="http://schemas.hp.com/SM/7/Common" 
xmlns:xmime="http://www.w3.org/2005/05/xmlmime" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://schemas.hp.com/SM/7 /SDToDo.xsd">
<instance query="" recordid="CM00106862 - cm3r" uniquequery="record.id=&quot;CM00106862&quot; and itemType=&quot;cm3r&quot;">
<TodoNumber type="String">CM00106862</TodoNumber>
<ToDoModule type="String">cm3r</ToDoModule>
<ToDoStatus type="String">submitted</ToDoStatus>
<ToDoDescription type="String">Portactivation Server SCHWARTZ3 C6000 Request and Network Configuration Request</ToDoDescription>
<ToDoAssignmentGroup type="String">XL/IOC GERMANY</ToDoAssignmentGroup>
<ToDoAssigneeName type="String">p591392</ToDoAssigneeName>
</instance>
<instance query="" recordid="IM02086084 - probsummary" uniquequery="record.id=&quot;IM02086084&quot; and itemType=&quot;probsummary&quot;">
<TodoNumber type="String">IM02086084</TodoNumber>
<ToDoModule type="String">probsummary</ToDoModule>
<ToDoStatus type="String">In Charge</ToDoStatus>
<ToDoDescription type="String">WBI-FN Operating rights for XL10033 expired?</ToDoDescription>
<ToDoAssignmentGroup type="String">XL/IOC GERMANY</ToDoAssignmentGroup>
<ToDoAssigneeName type="String">p707112</ToDoAssigneeName>
</instance>
<instance query="" recordid="IM02135674 - probsummary" uniquequery="record.id=&quot;IM02135674&quot; and itemType=&quot;probsummary&quot;">
<TodoNumber type="String">IM02135674</TodoNumber>
<ToDoModule type="String">probsummary</ToDoModule>
<ToDoStatus type="String">In Charge</ToDoStatus>
<ToDoDescription type="String">G00PSMP1: Event ID: 432, FILE, ERROR =&gt; SollShares =&gt; 430 =&gt; 432</ToDoDescription>
<ToDoAssignmentGroup type="String">XL/IOC GERMANY</ToDoAssignmentGroup>
<ToDoAssigneeName type="String">p518731</ToDoAssigneeName>
</instance>
<instance query="" recordid="TM00059273 - cm3t" uniquequery="record.id=&quot;TM00059273&quot; and itemType=&quot;cm3t&quot;">
<TodoNumber type="String">TM00059273</TodoNumber>
<ToDoModule type="String">cm3t</ToDoModule>
<ToDoStatus type="String">submitted</ToDoStatus>
<ToDoDescription type="String">Tributum Server Downtime - Tivoli Task</ToDoDescription>
<ToDoAssignmentGroup type="String">XL/IOC GERMANY</ToDoAssignmentGroup>
<ToDoAssigneeName type="String">xl10033</ToDoAssigneeName>
</instance>
<instance query="" recordid="TM00059274 - cm3t" uniquequery="record.id=&quot;TM00059274&quot; and itemType=&quot;cm3t&quot;">
<TodoNumber type="String">TM00059274</TodoNumber>
<ToDoModule type="String">cm3t</ToDoModule>
<ToDoStatus type="String">submitted</ToDoStatus>
<ToDoDescription type="String">Tributum disable mainframe ressource</ToDoDescription>
<ToDoAssignmentGroup type="String">XL/IOC GERMANY</ToDoAssignmentGroup>
<ToDoAssigneeName type="String">xl10033</ToDoAssigneeName>
</instance>
<instance query="" recordid="TM00059278 - cm3t" uniquequery="record.id=&quot;TM00059278&quot; and itemType=&quot;cm3t&quot;">
<TodoNumber type="String">TM00059278</TodoNumber>
<ToDoModule type="String">cm3t</ToDoModule>
<ToDoStatus type="String">submitted</ToDoStatus>
<ToDoDescription type="String">Tributum Server Downtime - Tivoli Task</ToDoDescription>
<ToDoAssignmentGroup type="String">XL/IOC GERMANY</ToDoAssignmentGroup>
<ToDoAssigneeName type="String">xl10033</ToDoAssigneeName>
</instance>
<instance query="" recordid="TM00059280 - cm3t" uniquequery="record.id=&quot;TM00059280&quot; and itemType=&quot;cm3t&quot;">
<TodoNumber type="String">TM00059280</TodoNumber>
<ToDoModule type="String">cm3t</ToDoModule>
<ToDoStatus type="String">submitted</ToDoStatus>
<ToDoDescription type="String">Tributum disable mainframe ressource</ToDoDescription>
<ToDoAssignmentGroup type="String">XL/IOC GERMANY</ToDoAssignmentGroup>
<ToDoAssigneeName type="String">xl10033</ToDoAssigneeName>
</instance>
<instance query="" recordid="TM00059504 - cm3t" uniquequery="record.id=&quot;TM00059504&quot; and itemType=&quot;cm3t&quot;">
<TodoNumber type="String">TM00059504</TodoNumber>
<ToDoModule type="String">cm3t</ToDoModule>
<ToDoStatus type="String">submitted</ToDoStatus>
<ToDoDescription type="String">Tributum disable mainframe ressource</ToDoDescription>
<ToDoAssignmentGroup type="String">XL/IOC GERMANY</ToDoAssignmentGroup>
<ToDoAssigneeName type="String">p568003</ToDoAssigneeName>
</instance>
</RetrieveSDToDoListResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>


我尝试使用以下代码,但最后我通过循环现有节点。 我知道应该有一种简单的方法来从节点“实例”和所有子项中获取所有项目。

最后,我需要一个DataView或DataTable继续我的应用程序。

public static string gettextfromWebserviceItems(string result)
    {
        StringBuilder builder = new StringBuilder();


        var doc = new XmlDocument();
        doc.LoadXml(result);
        var ns = new XmlNamespaceManager(doc.NameTable);
        ns.AddNamespace("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
        //XmlNodeList nodes = doc.SelectNodes("/SOAP-ENV:Envelope/SOAP-ENV:Body/RetrieveSDToDoListResponse/instance", ns);
        XmlNodeList nodes = doc.GetElementsByTagName("instance");

        List<string> elementNamesList = new List<string>();
        elementNamesList.Add("TodoNumber");
        elementNamesList.Add("ToDoModule");
        elementNamesList.Add("ToDoStatus");
        elementNamesList.Add("ToDoDescription");
        elementNamesList.Add("ToDoAssignmentGroup");
        elementNamesList.Add("ToDoAssigneeName");

        foreach (XmlNodeList node in nodes)
        {

            //foreach (XmlAttribute v in node.Attributes)
            //{
            //    var value = v;
            //    //Do the processing

            //}


        }

如果有一个像SAX这样的外部DLL的简单解决方案,那么请告诉我......

提前谢谢你, 来自慕尼黑的祝福

2 个答案:

答案 0 :(得分:0)

XSD文件可以相对容易地转换为C#类定义。您发布的XML中包含以下属性:xsi:schemaLocation="http://schemas.hp.com/SM/7 /SDToDo.xsd"

使用此功能,您可以使用xsd.exe将XSD解析为C#,以便与XmlSerializer一起使用(这是一个糟糕的主意,我也不会这样做),或者您可以使用C#类作为在不使用XmlSerializer的情况下创建自己的模型和翻译器的基础(使用XNode而不是XmlDocument API)。

一旦它以对象形式出现,就可以相对轻松地变成DataTableDataView(或者您可以直接进行,无论您喜欢哪种方式)。< / p>

答案 1 :(得分:0)

与前面的发言者不太一致。是的,它将以对象形式出现,但将对象数组转换为DataTable并不容易。 在你的情况下你很幸运你的信封,xml是DataTable xml格式的精确表示,你可以只使用ReadXml方法

// your code, practically unchanged
XmlDocument doc = new XmlDocument();
doc.LoadXml(result);
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
ns.AddNamespace("XZ", "http://schemas.hp.com/SM/7");
XmlNode node = doc.SelectSingleNode("SOAP-ENV:Envelope/SOAP-ENV:Body/XZ:RetrieveSDToDoListResponse", ns);

if(node!=null)
{
    //define your table
    DataTable dt = new DataTable();
    dt.Columns.Add("TodoNumber", typeof(string));
    dt.Columns.Add("ToDoModule", typeof(string));
    dt.Columns.Add("ToDoStatus", typeof(string));
    dt.Columns.Add("ToDoDescription", typeof(string));
    dt.Columns.Add("ToDoAssignmentGroup", typeof(string));
    dt.Columns.Add("ToDoAssigneeName", typeof(string));
    dt.TableName = "instance";

    string content = "<DocumentElement>" +
        //DIRTY HACK TO REMOVE NAMESPACE
            node.InnerXml.Replace("xmlns=\"http://schemas.hp.com/SM/7\"", "")
         + "</DocumentElement>";

    //this code makes the trick
    using(MemoryStream  ms=new MemoryStream(Encoding.UTF8.GetBytes (content)))
    {
        dt.ReadXml(ms);    
    }

}