Getting Started with SOAP-Based Web Services and PowerShell

Getting Started with SOAP-Based Web Services and PowerShell

PowerShell's Invoke-WebRequest handles SOAP wonderfully

This month, I'll continue my how-to series about using PowerShell's Invoke-WebRequest cmdlet to query online Web services by moving from the newer RESTful-type Web services to the older (but still extant) SOAP-type Web services. The housing market is slowly recovering in the United States, so you might appreciate having easy access to payment information via a Web service that I'll introduce this month!

Let's query a free public SOAP service hosted (and well documented, thankfully) by www.webservice.net. Its Mortgage Web Service (MWS) accepts a loan period in years, interest rate in percent, total house loan amount, and annual taxes and insurance. It then grinds the numbers and returns the total projected monthly payment.

Take a look at MWS's home page, and find the Endpoint heading. Under that is MWS's URI:

http://www.webservicex.net/mortgage.asmx?WSDL

Notice two things. First, the URI has an .asmx extension. That's almost always the extension of a SOAP URI. Second, notice the query string ?WDSL. That is a reference to some XML that allows this Web service to describe itself and its required inputs to the outside world, and what it will provide in return. (That will be important next month, when I use something called a "Web service proxy" to simplify calling this service.)

Below the URI, you'll see GetMortgagePayment. That's the name of the "method" in this Web service. MWS has only one method, but you'll run into many more Web services that have more than one method. Click GetMortgagePayment to reveal an area with the title SOAP 1.1. This area shows how to create an XML file that feeds MWS the inputs that it needs, with the inputs entered as elements in the XML.

The text in that figure is the entirety of the SOAP text that MWS needs, but you needn't put all that in your file, as PowerShell automatically inserts everything up to and including the SOAPAction… line.

To build the SOAP XML file, copy everything from onward, as seen here, into Notepad:

Next, you'll supply values for the five inputs. For example, notice int. The length of the loan in years is to be supplied as an XML element  named . The int is just placeholder text to clue you to enter an integer in there. Assume that it's a 30-year mortgage, so replace int with 30. Next is , and that's double, which means that it accepts any floating-point number. Let's make that 4.2 percent, and thus it is 4.2. Assume a loan amount of $250,000, and skip the taxes and insurance by setting them each to 0. Fill in those values, and save the file as Payments.XML. The result will look like the following (notice I let Notepad just wrap the long first line):

You'll deliver the query via Invoke-Webrequest, but SOAP requests must normally be POSTed, not GETed. You must also tell Invoke-Webrequest to send the Payments.xml file and, as a side effect of POSTing rather than GETing, you've got to tell Invoke-Webrequest what sort of returned data to expect (text and XML, in this case). This will do it all, storing the result in $Result:

$URI = " http://www.webservicex.net/mortgage.asmx?WSDL"
$result = (iwr $URI –infile payments.xml –contentType "text/xml" –method POST)

SOAP services return their answers in a SOAP-style XML text that you can find in $Result.Content. Take a look at the SOAP XML result by typing

$result.content

You'll see some unformatted XML, and amidst it you'll see your payment amount:

1222.5429342838054

Once again, this means that you'll need PowerShell to pluck out one bit of text (the payment) from a specific element () in an XML structure. As you've done before, you'll use Select-XML. First, put the XML in its own variable for clarity:

$SOAP = $Result.Content

To get a better look at the XML, save $SOAP into a file and open it with almost any Web browser. You'll get a nicely indented view of the XML so that you know exactly what kind of data this service offers. (Just don't use Edge, which seems XML-deaf at this writing.) Then, define the Xpath query that will pluck out the one TotalPayment element, as I described in an earlier article:

$xpathfilter = "//*[local-name()='TotalPayment']"

Next, do the Select-XML to capture the element:

$Element = Select-XML –content $SOAP –xpath $xpathfilter

Type $Element, and you'll just see that there are three attributes: node (which contains your data), path, and pattern. Type $Element.node, and you'll see that there is just one attribute, #text, which contains your payment amount. You can get it all in one line by appending .node and .'#text' —recall that you need the single quotes because although XML understands "#text", PowerShell just sees everything after an octothorpe as a comment:

$Payment = $Element.Node.'#text'

Just think: If everyone had known PowerShell and Invoke-Webrequest between 1999 and 2008, the housing crisis might never have happened! That's neat, but I could live without having to build XML files, and I bet you could too, so don’t miss my coverage of Web service proxies next time!

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish