Class 25 Using Multiple Schemas

Handout: orderDap schemas

Handout:  SOAP and WSDL Example

 

A particular <schema> is associated with a particular targetNS, where its names reside (in our imagination, anyway).  So using two NS’s necessarily involves two <schema>’s, normally in two schema docs.

Link.xsd

<link> elements have the new NS with “/dap” at the end of the URI. Link.xsd is not complicated, just 3 attributes in the one <link> element which is itself global, so we don’t need elementFormDefault=”qualified”—that’s only needed when we have non-global elements.

The attributes are themselves non-global, i.e. “local” in the schema sense, because their declarations <attribute…> are not direct children of <schema>, because of the enclosing <link> element. Using the default attributeFormDefault =”unqualified”, we never use prefixes on local attributes, and they belong to no namespace.

Compare <link> to XLink, covered in notes09.html, which worked with global attributes, to support linkage from any element that allowed global attributes in its schema.

OrderDap.xsd

The greater challenge is understanding OrderDap.xsd.  It imports Link.xsd to make its <link> element declaration usable in its own schema. The <import> element has an attribute listing the imported NS to make sure the right thing gets imported: this must match the targetNS of the imported schema. The schemaLocation says where it is, here “Link.xsd” to say it’s in the same directory as this schema.

In order to use the imported NS names, a prefix is declared, here ns1.  It’s used in ref=”ns1:link” to put a <link> element in the “representation” type. Note that ref is typed as QName in the schema of schemas, just like type (see notes09.html).  Recall that name is typed as NCName (no-colon name), because when we use it we are introducing names into the target NS, so we have no choice about the NS. But types and ref’d elements can come from other NS’s, as we see here.

The representation type is itself abstract. Like an abstract Java class, we can’t use this type directly, only by extending it.  The extensions add more things to the sequence, after the <link> elements of the base.

Type extension can add attributes as well as children—see the schema primer.

In this case we only needed the one element <link>, but in other cases we could import schema types and build our own types and elements based on imported + local schema.

Type extension is used in Harold Chap. 1, so we should cover that case too!  See the end of the handout:

Another use of type extension, from Harold’s order.xsd, Chap 1: add an attribute to a SimpleType, making it a ComplexType.

<xsd:complexType name="MoneyType">

    <xsd:simpleContent>

      <xsd:extension base="xsd:decimal">

        <xsd:attribute name="currency" type="xsd:string"/>

      </xsd:extension>

    </xsd:simpleContent>

  </xsd:complexType>

 

In the XML: an element of type MoneyType:

<Total currency='USD'>290.79</Total>

 

Why does such a simple XML construct need type extension to describe it?  We need to put it in context of the whole schema typing system to try to answer that.

First, we note that the type we need is a complex type, since a simple type may not have children elements or attributes.

Using XPath nodes as our basic model of XML structure, we see that a text node can be described by a SimpleType when it forms the content of an element:

Picture:   <element>à<text>   [picture should be vertical]

And this is very common at the leaves of our XML trees.

The structure of the interior of the XML tree, we usually see:

<element>à <attribute>,…

               à<element>,… children

With no text nodes in between, and this is what can be described by our usual XML Schema complexType declarations with sequences, etc.

If there are text nodes in between, we say the element has “mixed content”, and XML Schema allows us to put mixed=”true” in the <complexType> declaration. But this only allows us to put untyped text nodes in between the children and before and after them, and the children still need to be ordered as specified. This is so restrictive as to be almost useless, so we don’t often use this option.

So, although we can type this XML by calling it “mixed” with an attribute, that’s not great and does not allow us to use a simple type for the content.

The only way out is to say the basic type is a simple type describing the text content, and extend it to add in the attribute.  Not pretty!

Sketch of example from XML Schema primer:  case of importing a type

IPO.xsd: has

<schema targetNamespace="http://www.example.com/IPO"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:ipo="http://www.example.com/IPO">

<simpleType name="SKU">

    <restriction base="string">

      <pattern value="\d{3}-[A-Z]{2}"/>

    </restriction>

  </simpleType>

</schema>

Report.xsd imports IPO.xsd and uses its SKU type:

<schema targetNamespace="http://www.example.com/Report"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:r="http://www.example.com/Report"
        xmlns:xipo="http://www.example.com/IPO"
        elementFormDefault="qualified">
 
  <!-- for SKU -->
  <import namespace="http://www.example.com/IPO"/>
 
  <complexType name="PartsType">
    <sequence>
      <element name="part" maxOccurs="unbounded">
        <complexType>
          <simpleContent>
            <extension base="string">
              <attribute name="number" type="xipo:SKU"/>
            </extension>
          </simpleContent>
        </complexType>
      </element>
    </sequence>
  </complexType>
 
</schema>

XML of type PartsType, suitable for <parts>:

<part number="872-AA">Lawnmower</part>
<part number="926-AA">Baby Monitor</part>
<part number="833-AA">Lapis Necklace</part>
<part number="455-BX">Sturdy Shelves</part>

 

What we’re seeing is again an element with string content AND an attribute. Now we know that means using type extension from the simple type describing the element content.

Anyway, we see type=”xipo:SKU” to use the type imported from the other schema.

<xsd:include> just includes other parts of schema for the same NS.  See the XML Schema Primer for examples.

SOAP Web Services

Read REST book, Chap. 11 The Web and WS-*

If interested in WSDL, see tutorial

 

But start now with Harold, pp. 96-99, 116-118, plus Appendix B, pp. 969-972,

firmly skipping all SOAP-ENC material (obsolete)

 

Basic scheme: use HTTP POST for all service request/responses, to a single service endpoint, i.e. one URL for the whole service. Use XML messages enclosed in SOAP “envelopes”.

 

So no idea of URI for each resource here.  Orders and payments, etc, are still described in XML as in REST, but are all hidden inside the SOAP server. You ask, in XML, for what you want and the server returns it.

 

The basic rules of designing WS actions is the same for SOAP and REST. Invent actions that depend only on the message and persistent state held by the server—that is the basic “stateless” rule. In other words, don’t expect the server to remember what you were doing last, even if you have to authenticate yourself to get the service.

 

So it’s straightforward to convert a REST service to a SOAP service or vice versa. You can even reuse the schema for the “representations” of REST—now they are related to the public view of the persistent objects being manipulated by the service.  We will be looking at Amazon S3 storage service. It uses one schema for both its SOAP and REST APIs.

 

In SOAP, there is a way to find out what requests the server can answer, via its WSDL.  Unlike WADL, WSDL is widely supported and used. REST proponents would say that REST doesn’t really need WADL, since the service should give you what to do next at each step. But it would be great to know how to get started.

 

Pg. 97 Basic examples of SOAP messages

 

<?xml version=”1.0”?>

<SOAP-ENV:Envelope

     xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”>   ßSOAP-ENV is a prefix

     <SOAP-ENV:Body>

          <getQuote xmlns=”http://namespaces.cafeconleche.org/xmljava/ch2/”>

              <symbol>RHAT</symbol>

          </getQuote>

     </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

 

and similar message for response

 

Here we see local names Envelope and Body of the SOAP envelope NS.

 

Notes on this simple SOAP message:

-         envelope in one standard NS

-         body in an app-related NS

-         no address

-         interoperable (like REST)

o       J2EE (TOMCAT, WEBSPHERE)

.NET solution

Internationalized: XML in UTF-8 (like REST)

 

Lack of address: keeping it free of transport mechanism: could be HTTP, SMTP, ..., as we saw for media types used in REST.

 

Schema for this SOAP Message XML

Schema for the body: See pg. 103 for schema for the request message, trading.xsd. It has our usual setup: default NS = targetNS, elementFormDefault=”qualified”.

 

<xsd:element name=”symbol” type=”...>

 This is introducing the local name “symbol” for the target NS. 

type = “StockSymbol” refers to the StockSymbol in the default NS.

 

We now look at how the SOAP envelope schema can handle the message part inside, which is designed by the app developers.  It’s similar to the XHTML example of class 11, except it tries to validate (processContents = “lax”) rather than skipping over the enclosed XML (processContents = “skip”).

 

Understanding the SOAP Envelope Schema

 

Not covered in class:

 

If we look at the SOAP Envelope schema in Appendix B, pg. 969, we see a different starting setup than we have been using for schemas:

 

<xsd:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:tns="http://schemas.xmlsoap.org/soap/envelope/”

targetNamespace=”http://schemas.xmlsoap.org/soap/envelope/”

 

We see there is no elementFormDefault=”qualified”.  It doesn’t matter, though, because all element definitions are global, i.e, their <element> definitions are direct children of <schema>.

Here “tns” means target NS, which it is by the third line. 

 

So there are more prefixes in this schema than we usually see:

<xs:element name=”Envelope” type = “tns:Envelope”/>

                                                                 ^^^ 

This prefix makes it very clear that the type name is in the NS, and strangely, they have both the element name “Envelope” and the type name “Envelope”, both in the namespace. There is one localname “Envelope” in the NS, with double duty as an element name and as a type name.  Similarly with Body.

 

It uses <any ...> to allow the app to fill in any message format in XML. The <any> element is on pg. 971, inside schema element name=”Body”.  The processContents = “lax” means try to use a schema if you can find one.

 

Validating a whole SOAP message: need to import one schema into another

 

This is another example of schema using two schemas together, here the SOAP envelope schema and the app schema for the contents of Body.  Need to import one schema into another. 

 

It’s a little different than our orderDap.xsd + Link.xsd because the outer schema doesn’t itself use the elements, etc., defined in the imported schema.  Consequently, it doesn’t need to define a prefix for the imported NS. Also, we aren’t in control of the outer schema (we shouldn’t edit it), so we need to expand from it in our own document, and this is where <include> comes in to use.

 

Harold shows us the way here, on pg. 117-118.  Drop the import of “.../soap/encoding”, which we’re not using, but keep the xsd:import of trading.xsd, and the xsd:include of the SOAP envelope schema. 

 

The <include> brings in the SOAP envelope document the way #include does in C, i.e., verbatim, so at top level of the result is the SOAP envelope schema. The <import> allows another NS’s schema to be helping out with the full schema.

 

It’s better to avoid the local URL in the schemaLocation value (here or anywhere), unless you are sure the validator knows what the base URL is.  Should be safe if in the same directory.

 

For more examples, if interested: see the W3C Schema Primer, linked to class web page.