Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have the following XML results that are generated when I run a SOAP request to a webservice.

XML
 <?xml version="1.0" encoding="utf-8" ?> 
- <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
- <SOAP-ENV:Body>
- <idc:service xmlns:idc="http://www.stellent.com/IdcService/" IdcService="SEARCH_WORKFLOWS">
- <idc:document dUser="user">
  <idc:field name="SearchAuthor" /> 
  <idc:field name="SearchCID">arf</idc:field> 
  <idc:field name="SearchAssn" /> 
- <idc:resultset name="WfDocuments">
- <idc:row dDocName="ARF16-0711" dID="596213" dDocType="JPS_QMARF" dDocTitle="ARF16-0711 AMYWSA3377 Prop Lbl Prod PV Mat LStatn" dDocAuthor="author" dRevClassID="283640" dRevisionID="1" dRevLabel="A0" dIsCheckedOut="0" dCheckoutUser="" dSecurityGroup="Submitted_Forms" dCreateDate="8/23/16 3:10 PM" dInDate="8/23/16 3:10 PM" dOutDate="" dStatus="REVIEW" dReleaseState="E" dFlag1="" dWebExtension="hcsp" dProcessingState="Y" dMessage="" dDocAccount="" dReleaseDate="" dRendition1="" dRendition2="" dIndexerState="" dPublishType="" dPublishState="">
</idc:row>
  </idc:resultset>
  </idc:document>
  </idc:service>
  </SOAP-ENV:Body>
  </SOAP-ENV:Envelope>


The full SOAP call string is https://auhjpsv01/stellent/idcplg?IdcService=SEARCH_WORKFLOWS&SearchAssn=&SearchCID=arf&SearchAuthor=&IsSoap=1[^]

I want to parse out the dDocName node data (ARF16-0711) and the dCreateDate node data (8/23/16 3:10 PM) to a text box, but keep getting the following error with my code.

HTML
<soap-env:envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:body>
<soap-env:fault>
<faultcode>Client</faultcode>
<faultstring>The Soap request is invalid.  The service node '(null)' is invalid.</faultstring>
</soap-env:fault>
</soap-env:body>
</soap-env:envelope>


What I have tried:

Here is my code.

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;

namespace SOAP_reference
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            setupWebServiceSOAPCall();            
        }

        public void setupWebServiceSOAPCall()
        {
            var _url = "https://auhjpsv01/stellent/idcplg?IdcService=SEARCH_WORKFLOWS&SearchAssn=&SearchCID=arf&SearchAuthor=&IsSoap=1";
            var _action = "https://auhjpsv01/stellent/idcplg?IdcService=SEARCH_WORKFLOWS&SearchAssn=&SearchCID=arf&SearchAuthor=&IsSoap=1";

            XmlDocument soapEnvelopeXml = CreateSOAPXMLEnvelope();
            HttpWebRequest webRequest = CreateSOAPWebRequest(_url, _action);
            InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);

            // begin async call to web request.
            IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);

            // suspend this thread until call is complete. You might want to
            // do something usefull here like update your UI.
            asyncResult.AsyncWaitHandle.WaitOne();

            // get the response from the completed web request.
            string soapResult;
            using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
            {
                using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
                {
                    soapResult = rd.ReadToEnd();
                }
                Console.Write(soapResult);
                textBox1.Text = soapResult;
            } 
        }

        private static HttpWebRequest CreateSOAPWebRequest(string url, string action)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Headers.Add("SOAPAction", action);
            request.ContentType = "text/xml;charset=\"utf-8\"";
            request.Accept = "text/xml";
            request.Method = "POST";
            return request;
        }

        private static XmlDocument CreateSOAPXMLEnvelope()
        {
            XmlDocument envelop = new XmlDocument();
            envelop.LoadXml(@"<idc:document duser="" gittlera="" xmlns:idc="#unknown"><idc:field name="" searchauthor="" /><idc:field name="" searchcid="">arf</idc:field><idc:field name="" searchassn="" /><idc:resultset name="" wfdocuments=""></idc:resultset></idc:document><soap-env:body xmlns:soap-env="#unknown"></soap-env:body>");
            return envelop;
        }

        private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
        {
            using (Stream stream = webRequest.GetRequestStream())
            {
                soapEnvelopeXml.Save(stream);
            }
        }
    }
}
Posted
Updated 29-Aug-16 16:55pm
v3

The way the question is worded makes me think you've already got the response from the web service but can't extract the info. you want? If so here's one way ...

Fake a call to the web service with a read only property returning the data to parse.
C#
/// <summary>
/// The data returned by the web service.
/// </summary>
public static string soapData {
  get {
    return @"<?xml version=""1.0"" encoding=""utf-8"" ?>
      <SOAP-ENV:Envelope xmlns:SOAP-ENV=""http://schemas.xmlsoap.org/soap/envelope/"">
        <SOAP-ENV:Body>
          <idc:service xmlns:idc=""http://www.stellent.com/IdcService/"" IdcService=""SEARCH_WORKFLOWS"">
            <idc:document dUser=""user"">
              <idc:field name=""SearchAuthor"" />
              <idc:field name=""SearchCID"">arf</idc:field>
              <idc:field name=""SearchAssn"" />
              <idc:resultset name=""WfDocuments"">
                <idc:row dDocName=""ARF16-0711"" dID=""596213""
                         dDocType=""JPS_QMARF""
                         dDocTitle=""ARF16-0711 AMYWSA3377 Prop Lbl Prod PV Mat LStatn""
                         dDocAuthor=""author""
                         dRevClassID=""283640"" dRevisionID=""1"" dRevLabel=""A0""
                         dIsCheckedOut=""0"" dCheckoutUser=""""
                         dSecurityGroup=""Submitted_Forms""
                         dCreateDate=""8/23/16 3:10 PM""
                         dInDate=""8/23/16 3:10 PM"" dOutDate=""""
                         dStatus=""REVIEW"" dReleaseState=""E"" dFlag1=""""
                         dWebExtension=""hcsp"" dProcessingState=""Y""
                         dMessage="""" dDocAccount="""" dReleaseDate=""""
                         dRendition1="""" dRendition2="""" dIndexerState=""""
                         dPublishType="""" dPublishState="""">
                </idc:row>
              </idc:resultset>
            </idc:document>
          </idc:service>
        </SOAP-ENV:Body>
      </SOAP-ENV:Envelope>";
  }
}


Now a method to extract the info. we're interested in. This is hard code to select only one type of node (it'll select all nodes of that type) and to extract only the attributes mentioned in the question.
C#
/// <summary>
/// Hard coded to read two attributes from a single node selected by xpath.
/// </summary>
/// <param name="soapmessage"></param>
public static void read(string soapmessage) {


  XmlDocument document = new XmlDocument();
  document.LoadXml(soapmessage);  //loading soap message as string

  // Set up the namespace for the idc service.
  // Need it to allow xpath selection of prefixed nodes.
  // Just for fun comment out these lines and use
  // document.SelectNodes("//idc:row") instead of the current call to see
  // what happens.
  XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
  manager.AddNamespace("idc", "http://www.stellent.com/IdcService/");

  XmlNodeList xnList = document.SelectNodes("//idc:row", manager);
  int nodes = xnList.Count;

  foreach (XmlNode xn in xnList) {
    // Get the attribute values of interest.
    // Attributes is a collection.
    // Beware null exception where an attribute is optional and isn't
    // found on a node.
    Console.WriteLine("Doc: {0} Created: {1}",
                      xn.Attributes["dDocName"].Value,
                      xn.Attributes["dCreateDate"].Value);
  }


}


and to test it...

C#
/// <summary>
/// Test it.
/// </summary>
public static void test() {
  read(soapData);
}


Output

Doc: ARF16-0711 Created: 8/23/16 3:10 PM


LINQ for XML is an alternative.
 
Share this answer
 
v2
Comments
AdvancedDNA 25-Aug-16 15:32pm    
Thanks cigwork. I think this would work if I take the response from the web service and access it directly. I will try it out and revise my question accordingly. To clarify, I am having trouble writing the SOAP envelope for the call. The return from this call is dynamic and will change nearly every hour, so I am trying to write program to place a priority on the return dDocName based on the dCreateDate to determine which item my team needs to work on first.
Maciej Los 25-Aug-16 16:00pm    
5ed!
Thank you for your post cigwork. One more question, the XML data that is pulled when I run the SOAP call has a bunch of fields, one of which I need to pull data from.. How do I go about pulling the value from idc:field name="dWfStepName?

I need to filter the list I am returning from the XML data based on the value of that field.

I am trying to pull a list of active workflows based on who is required to perform an action on them. If dWfStepName = Workcell, I don't want the dDocName in the list, otherwise if it contains anything else, I want to populate the list with the dDocName and dCreateDate.

<?xml version="1.0" encoding="utf-8" ?>
- <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
- <SOAP-ENV:Body>
- <idc:service xmlns:idc="http://www.stellent.com/IdcService/" IdcService="SEARCH_WORKFLOWS">
- <idc:document dUser="user">
<idc:field name="SearchAuthor" />
<idc:field name="SearchCID">arf</idc:field>
<idc:field name="SearchAssn" />
- <idc:resultset name="WfDocuments">
- <idc:row dDocName="ARF16-0711" dID="596213" dDocType="JPS_QMARF" dDocTitle="ARF16-0711 AMYWSA3377 Prop Lbl Prod PV Mat LStatn" dDocAuthor="author" dRevClassID="283640" dRevisionID="1" dRevLabel="A0" dIsCheckedOut="0" dCheckoutUser="" dSecurityGroup="Submitted_Forms" dCreateDate="8/23/16 3:10 PM" dInDate="8/23/16 3:10 PM" dOutDate="" dStatus="REVIEW" dReleaseState="E" dFlag1="" dWebExtension="hcsp" dProcessingState="Y" dMessage="" dDocAccount="" dReleaseDate="" dRendition1="" dRendition2="" dIndexerState="" dPublishType="" dPublishState="">
<idc:field name="dWfID">1741</idc:field>
<idc:field name="dWfDocState">INPROCESS</idc:field>
<idc:field name="dWfComputed" />
<idc:field name="dWfCurrentStepID">6168</idc:field>
<idc:field name="dWfDirectory">submitted_forms</idc:field>
<idc:field name="dClbraName" />
<idc:field name="dWorkflowState">R</idc:field>
<idc:field name="dRevRank">0</idc:field>
<idc:field name="xReferenced_By" />
<idc:field name="xNew_Assembly">No</idc:field>
<idc:field name="xNew_Product_Containment" />
<idc:field name="xBay_Number" />
<idc:field name="xWave_Number" />
<idc:field name="xCell_Number" />
<idc:field name="xVendor" />
<idc:field name="xPlant" />
<idc:field name="xIndustry" />
<idc:field name="xAffected_Departments" />
<idc:field name="xIDCPlacement" />
<idc:field name="xProduct_Group" />
<idc:field name="xIDCWatermark">None</idc:field>
<idc:field name="xCustomer">Amway</idc:field>
<idc:field name="xIDCSecureChange" />
<idc:field name="xIDCSecurePrint">Enable</idc:field>
<idc:field name="xIDCSecureSelect" />
<idc:field name="xIDCSecureNotes" />
<idc:field name="xSystem_Internal" />
<idc:field name="xImpacts_EMS" />
<idc:field name="xCustomer_ECO_Number" />
<idc:field name="xDistribution" />
<idc:field name="xCustomer_Deviation" />
<idc:field name="xAssembly_Number">AMYWSA3377</idc:field>
<idc:field name="xPart_Number" />
<idc:field name="xComments" />
<idc:field name="xReference_Documents">,</idc:field>
<idc:field name="xworkflowRouting" />
<idc:field name="xphase" />
<idc:field name="xAssigned">dawkinsd</idc:field>
<idc:field name="xTraining">No</idc:field>
<idc:field name="xVerification">No</idc:field>
<idc:field name="xValidation">Yes</idc:field>
<idc:field name="temp_xcustomer_eco_number" />
<idc:field name="temp_xcustomer_deviation" />
<idc:field name="dWfStepName">Workcell</idc:field>
<idc:field name="dWfStepID">6168</idc:field>
<idc:field name="dWfStepDescription" />
<idc:field name="dWfStepType">:R:</idc:field>
<idc:field name="dWfStepIsAll">0</idc:field>
<idc:field name="dWfStepWeight">1</idc:field>
<idc:field name="dWfName">Amway_JPS_ARF_WF</idc:field>
<idc:field name="dWfDescription" />
<idc:field name="dCompletionDate" />
<idc:field name="dWfStatus">INPROCESS</idc:field>
<idc:field name="dWfType">SubWorkflow</idc:field>
<idc:field name="dProjectID" />
<idc:field name="dIsCollaboration">0</idc:field>
</idc:row>
</idc:resultset>
</idc:document>
</idc:service>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I tried setting up
XmlNode node = xn.SelectSingleNode("idc:field name='dWfStepName'")
but kept getting the following error
C#
'idc:field name='dWfStepName'' has an invalid token.

I apologize for asking what seems to be like simple questions. I am very new to XML. Most of my background is with LabView, C++, C# and SQL.

cigwork edit

Have a look at ... http://www.w3schools.com/xsl/xpath_syntax.asp

In this case you're interested in selecting nodes by attributes and the value is the innertext of the node.

C#
XmlNodeList xnList = document.SelectNodes("//idc:field[@name='dWfStepName']", manager);
     int nodes = xnList.Count;

     foreach (XmlNode xn in xnList) {
       Console.WriteLine("Step Name: {0}",
                         xn.InnerText);
 
Share this answer
 
v2
Comments
Patrice T 29-Aug-16 15:04pm    
Do not use a solution to ask another question.
If you want large audience, open a new question.
FINAL SOLUTION:
Thanks again cigwork for your help. Now I can build a priority list and when I run the SOAP call I can adjust the priority by what has fallen off the list, what is new and what is still there.

There is more code than this (about 50K lines, and this XML piece was the final piece to the puzzle!!!).

C#
XmlNodeList xnList = document.SelectNodes("//idc:row", manager);
            int nodes = xnList.Count;
            string step = null;

            foreach (XmlNode xn in xnList)
            {
                var doc = xn.Attributes["dDocName"].Value.ToString();

                XmlNode WFStep = document.SelectSingleNode("//idc:row[@dDocName='"+doc+"']/idc:field[@name='dWfStepName']", manager);
                 
                 //foreach (XmlNode xn1 in xnList1)
                 //{
                     step = WFStep.InnerText.ToString();
                 //}

                listBox1.Items.Add("Doc: " + xn.Attributes["dDocName"].Value.ToString() 
                    + ". Revision: " + xn.Attributes["dRevLabel"].Value.ToString() 
                    + ". Created Date: " + xn.Attributes["dCreateDate"].Value.ToString() 
                    + ". Status: " + xn.Attributes["dStatus"].Value.ToString() 
                    + ". Step: " + step
                    );
            }
        }
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900