Support Play: How to verify and troubleshoot rules created from XSD or WSDL by Accelerators
Summary
When the services or connectors in your application will exchange XML documents with an external system, you use the Import XSD/DTD Accelerator and/or the Connector accelerator, as appropriate, to generate classes, properties, and other rules that manage the data.
- When implementing services that process XML, typically SOAP or dotNET, you use the Import XSD/DTD Accelerator. It uploads and analyzes either a Document Type Definition (DTD) or an XML Schema Definition (XSD) file that you obtain or create.
- For SOAP and dotNET connectors, the Connector Accelerator imports the WSDL file of the external service – a WSDL file that may contain schema. If you need XML parse and stream rules for connectors, you then run the Import XSD/DTD Accelerator after running the Connector Accelerator and using the same base class.
This article describes how the accelerators interpret schema and presents problem/resolution identification strategies to use when the source XSD could not be interpreted as you intended it should.
Quick Links
Background: How the Accelerators Interpret Schema
Declarations
Data Types
Extensions and Restrictions
- Simple content extensions
- Simple content restrictions
- Complex content extensions
- Complex content restrictions
- Substitution groups
Complex Content Models
- Sequence, choice, and all groups
- Partially defined content
- Mixed content
- Repeating content
- Reusable element and attribute groups
Include or Import and Namespace
Problems with XML Parse and Stream Rules
- Clipboard data is missing or incomplete after XML parse rule maps incoming data
- XML stream rules produce instances that are missing data
- XML stream rules produce invalid instances that don’t pass validation by the external system
Problems with SOAP Messages
- Outbound SOAP message does not contain the data needed by the external system
- Data from incoming SOAP message isn't mapped to the clipboard can't be mapped
- External system returns SOAP fault reporting XML validation error
SOAP Connector Problems
- java.lang.InstantiationException
- SAXException: Unregistered type: class java.lang.Object
- SAXException: No deserializer for {http://www.w3.org/2001/XMLSchema}anyType
- SAXException: Invalid element in xxx.yyy SomeElement - SubstituteElementName
Cause of Problems in the Source XSD Files
- Un-typed elements or attribute declarations
- Element or attribute wildcard components
- Element substitution groups
- Nested choice and sequence groups
- Repeating content groups
- Complex type extensions
- Abstract base types
- Mixed content
- Scalar value constraints
Background: How the Accelerators Interpret XSD
Generally speaking, the accelerators create class rules for each complex element or type defined in the schema document and create properties for each element or attribute in the complex element or type. The Import XSD/DTD accelerator also generates XML parse and stream rules. For general information, see Data Mapping XML.
However, there are certain XSD constructs that can be difficult for Process Commander to interpret and transform into class or property rules or to interpret appropriately in an XML parse or stream rule. This section describes how the Process Commander accelerators interpret specific XML schema components, providing information that you may need if the XSD file you imported was not interpreted as you expected.
Declarations
This section describes how the accelerators interpret complex element, scalar element, and attribute declarations.
Complex Element Declarations
The accelerators generate a Process Commander class that represents an element if the element declaration contains an anonymous complex type definition. The name of the new class rule is: [the name of the base class specified by the user]–[element name].
The accelerators generate properties for the new class as follows:
- Single-value properties for each attribute or scalar sub-element that is included in the element’s content model.
- Embedded page properties for each complex sub-element included in the element’s content model.
If an element declaration references a named complex type definition, the resulting class rule is generated for the complex type, not the complex element.
Scalar Element and Attribute Declarations
For each time a scalar element or attribute declaration is referenced from the content model of a complex element declaration or type definition, the accelerators generate a Single Value
property. This property:
- Belongs to the class that is generated for the complex element or type
- Is derived by the built-in or custom simple type that is referenced by the scalar element or attribute declaration
- Uses the name specified by the declaration
Data Types
This section describes how the accelerators interpret data type definitions and how the standard simple types defined by the XML schema specification map to Process Commander types.
Built-in Simple Types
The built-in types defined by the XML Schema specification are used to determine the type of all generated single-value properties. The following table presents how the built-in XSD types map to the set of single-value property types.
XSD type | Property type |
---|---|
string | String |
normalizedString | String |
base64Binary | String |
hexBinary | String |
token | Identifier |
Name | Identifier |
NCName | Identifier |
NMTOKEN | Identifier |
NMTOKENS | Identifier |
IDREF | Identifier |
IDREFS | Identifier |
IDREFS | Identifier |
ENTITY | Identifier |
ENTITIES | Identifier |
NOTATION | Identifier |
QName | Identifier |
anyURI | Identifier |
duration | Identifier |
gYear | Identifier |
gYearMonth | Identifier |
gMonth | Identifier |
gMonthDay | Identifier |
gDay | Identifier |
int | Integer |
short | Integer |
byte | Integer |
unsignedInt | Integer |
unsignedShort | Integer |
unsignedByte | Integer |
integer | Integer |
negativeInteger | Integer |
positiveInteger | Integer |
nonNegativeInteger | Integer |
nonPositiveInteger | Integer |
long | Decimal |
unsignedLong | Decimal |
decimal | Decimal |
float | Double |
double | Double |
boolean | True or False |
date | Date |
dateTime | DateTime |
time | Time of Day |
Custom Simple Types
Simple type definitions are known as “custom” simple types, because they are defined as derivations of the built-in simple types. When an attribute or scalar element is declared using a custom simple type, the accelerators use the built-in base type that the custom type is derived from to determine the type for the single-value property.
Custom types can restrict the character content of the built-in base type through the use of "facets" such as "totalDigits," for example. However, the only facets that currently affect the generation of property rules are "maxLength" and “enumeration.”
- A maxLength facet value is stored as the Maximum Length value on the Definition tab of the generated property rule.
- Enumeration facet values are stored in the generated property rules as Local List values on the Table Edit tab.
To enforce any other restrictions, you need to create validation rules.
Complex Type Definitions
For each named complex type definition, the accelerators generate a Process Commander class rule. The content model of the complex type definition determines the properties generated for the new class rule. The name of the class is: [the base class specified by the user]-[complex type name]. The content model for the complex type may group sub-elements into sequence, choice, or all groups, or may be derived from another complex type definition.
Extensions and Restrictions
This section describes how the accelerators interpret extensions or restrictions for simple and complex content.
Simple Content Extensions
This kind of complex type definition allows attributes to be added to scalar element values. In this case, the accelerators generate a class with properties for each declared attribute, and a special property called “Value” to hold the character content of the element.
Simple Content Restrictions
Simple content restrictions place restrictions on the attributes or character content of a complex type defined with a simple content extension. Process Commander responds to simple content restrictions as it does for simple type definitions: the accelerators create a new class rule that fully inherits from the class rule generated for the complex base type, but all specified character content restrictions are ignored because there is no way to represent them in the class definition.
Complex Content Extensions
Complex content extensions allow element or attribute declarations to be added to the content model of a complex base type. The accelerators generate class rules that correctly match the inheritance model specified by the schema.
However, dynamically overriding base types with instances of the extended types at runtime (that is, polymorphism) is not currently supported by the generated XML parse rules and stream rules. You must modify the generated XML parse and stream rules to support the desired runtime behavior.
Complex Content Restrictions
Complex content restrictions are used to define complex types that inherit the content model of a complex base type, with some of the element or attribute content excluded (in the derived type).
As with most object-oriented programming environments, Process Commander does not support this type of inheritance. When the accelerators encounter such a definition, they create the subclass (complex type) without any properties of its own, and all of the superclass properties are inherited, regardless of the content restrictions specified by the schema.
Substitution Groups
Substitution groups declare elements as being valid substitutes for other elements. This kind of construct is a variation on complex content extensions, because the substitutable element types must be compatible with each other. The difference between substitution groups and complex content extensions is this: in addition to defining interchangeable content models, the schema declares that the element names associated with a type are also interchangeable.
As with complex content extensions, substitution groups are not natively supported by the generated XML parse and stream rules. You must modify the XML parse and stream rules or configure activities that provide the behavior you need at runtime.
Complex Content Models
This section describes how the accelerators interpret XSD constructs that specify content models that are difficult for the accelerators to interpret programmatically.
Sequence, Choice, and All Groups
Content models for complex types might group sub-elements into sequence, choice, or all groups. While the accelerators create properties for all the elements that are contained in these groups, they cannot enforce the semantics of complicated content models.
For example, because sequence and choice groups can be nested within each other, whole sequences of elements could be optional or interchangeable according to the schema. This kind of complexity cannot be reproduced in the generated data model. The accelerators traverse the content model in depth-first order, and create properties for each element encountered. If the same element is used more than once in the same content model, the accelerators generate only one property.
Partially Defined Content
A schema can leave the content model of an element partially defined, allowing the content to be interpreted by the application doing the processing at runtime. If the schema uses the “any” or “anyAttribute” components, or defines elements that either have no type or use the built-in “anyType” base type, the accelerators cannot produce a complete set of class definitions for the schema.
When the accelerator determines the need to generate a property for an un-typed element, it creates an embedded page property of class @baseclass. If the un-typed element can occur more than once, the accelerator creates a page list property of type @baseclass. To use these properties at runtime, a concrete type must be substituted for the un-typed value, either in the XML data being received, or the clipboard page data being sent.
In such a case you would manually add the classes and properties necessary to support the expected processing after the accelerator finished. Additionally, you would modify the XML parse and stream rules to reference the classes you added manually so they provide the runtime behavior you need.
Mixed Content
Because XML is also used as a markup language for annotating text, complex element or type can be declared as having "mixed" content – that is, character content mixed in with element content. Mixed content is often used in conjunction with the "any" component to allow any text markup to occur between the opening and closing tags of an element.
Process Commander has no such construct, so the accelerators ignore the mixed content identifier. The accelerators create a class for the complex element or type that has appropriate properties for all declared sub-elements, but the character content must be XML encoded at runtime or Process Commander will attempt to parse it.
Repeating Content
The “maxOccurs” attribute is used to modify a local element declaration or element reference in the content model of a complex element or type. Process Commander interprets the maxOccurs attribute as follows: if the maxOccurs attribute exists, and is set to “unbounded” or a numeric value greater than one, a list property is generated – a value list for a simple element and a page list for a complex element.
However, the maxOccurs attribute can also appear in a sequence or choice group component. Like nested content model groups, this adds a kind of complexity to the content model that Process Commander does not reproduce in its class definitions. If the maxOccurs attribute appears in a choice or a sequence group rather than for an individual element, the accelerators ignore it.
Reusable Element and Attribute Groups
Reusable element and attribute groups allow content models to be built from reusable global schema components. The accelerator treat each reference to a global element or attribute group it as if it was defined locally within the content model and generates a property or embedded class, as appropriate, for each reference.
Include or Import and Namespace
This section describes how the accelerators interpret an XSD file with links to other XSD documents and how they create namespace identifiers.
Linked XML Schema Files
An XML Schema document can be linked to other XML Schema documents through the use of “include” or “import” components.
- The include component adds definitions to the same target namespace as the base document.
- The import component declares dependencies on definitions from different target namespaces than the base document.
- The “schemaLocation” attribute of the include or import components identifies the URI of the external document.
If the document URI can be resolved, the definitions included in the referenced document will be included in the generated data model.
Namespaces and Validation
XML Schema uses URI values (which may or may not equal the URI of the actual schema document) as namespace identifiers to prevent name collisions between the global components imported from different schema documents. The namespace identifiers defined by the schema appear as properties of the generated XML parse and stream rules, but are otherwise are ignored by Process Commander.
The generated parse rules do not perform runtime XML validation by default. However, you can enable XML validation by opening the rule and selecting the XML validation option. When validation is enabled, the parse rule performs full namespace-qualified XML validation against the original schema document prior to mapping XML data to the clipboard.
Name Collisions
Name collisions can occur for a variety of reasons when generating rules from schema definitions.
- While type definitions in XML have compound, namespace-qualified names, Process Commander class rules have a single key value as an identifier.
- While type names in XML may be of arbitrary length, Process Commander limits name lengths.
- In XML, names are case-sensitive so two type names that differ in case only are considered different names. Names in Process Commander are case insensitive.
In all of these situations, the accelerator attempts to generate unique, valid names for all generated rule instances.
Reserved Words
Sometimes element names from the XSD cannot be used as class or property names because they conflict with words that have special meaning in Process Commander. For example:
- Elements or attributes cannot begin with the strings px, py, or pz
- Elements or attributes cannot use the word Primary
Update: In Version 5.3, the accelerators display a form that lets you modify the names of rules that if created conflict with existing rules.
Symptoms
After using an accelerator to import an XSD file or a WSDL file that contains XSD, examine the results to determine whether the accelerator interpreted the schema as you intended it should. Some issues may not appear until you test the service or connector that exchanges XML with the external system.
If the schema contained declarations or definitions that were not interpreted as you intended, or, if your implementation is behaving unexpectedly, consult the following list of symptoms and then follow the links to the sections that describe issues in the source schema description that could be the reason for your problem.
Problems with XML Parse and Stream Rules
This section lists problems with the way generated parse and stream rules interpret data.
Symptom: Clipboard data is missing or incomplete after using XML parse rules to map inbound XML
Possible causes:
Un-typed elements declarations
Element or attribute wildcards
Element substitution groups
Nested choice and sequence groups
Repeating content groups
Complex type extensions
Mixed content
Symptom: XML stream rules produce instances that are missing the data needed by the external system
Possible causes:
Un-typed elements declarations
Element or attribute wildcards
Element substitution groups
Nested choice and sequence groups
Repeating content groups
Complex type extensions
Mixed content
Symptom: XML stream rules produce invalid instances; external system reports validation errors for message
Possible causes:
Nested choice and sequence groups
Abstract base types
Scalar value constraints
Problems with SOAP Messages
This section lists possible reasons why SOAP messages don't contain the data they should or aren't mapped correctly.
Symptom: Outbound SOAP message does not contain the data needed by the external system
Possible causes:
Un-typed elements declarations
Element or attribute wildcards
Element substitution groups
Nested choice and sequence groups
Repeating content groups
Complex type extensions
Mixed content
Symptom: Data from incoming SOAP message isn't being mapped to the clipboard
Possible causes:
Un-typed elements declarations
Element or attribute wildcards
Element substitution groups
Nested choice and sequence groups
Repeating content groups
Complex type extensions
Mixed content
Symptom: The external system returns a SOAP fault that reports an XML validation error
Possible causes:
Nested choice and sequence groups
Abstract base types
Scalar value constraints
SOAP Connector Exceptions
This section lists exceptions that can appear when a SOAP connector is called with the Connect-SOAP activity method.
java.lang.InstantiationException
Cause:
SAXException: Unregistered type: class java.lang.Object
Cause:
Un-typed attribute declaration
SAXException: No deserializer for {http://www.w3.org/2001/XMLSchema}anyType
Cause:
SAXException: Invalid element in xxx.yyy.SomeElement - SubstituteElementName
Cause:
Cause of Problems in Source XSD
This section describes constructs in source XSD files that Process Commander cannot always interpret correctly. For each issue, this section describes what to look for, explains why it is a problem and what to do about it, and provides examples.
Problem: Un-typed elements or attribute declarations
What to look for:
- Element declarations that do not contain a type attribute, or that contain a type="xs:anyType"
- Attribute declarations that do not contain a type attribute or that contain a type= "xs:anyScalarType"
Example:
XSD Definition of MyElem1:
<!-- contains child elements and attributes with no type information -->
<xs:element name=”MyElem1”>
<xs:complexType>
<xs:sequence>
<xs:element name=”ChildElem1”/>
<xs:element name=”ChildElem2” type=”xs:anyType”/>
</xs:sequence>
<xs:attribute name=”attr1”/>
<xs:attribute name=”attr2” type=”xs:anyScalarType”/>
</xs:complexType>
</xs:element>
Legal instances of MyElem1:
<MyElem1 attr1=”aaa” attr2=”bbb”>
<ChildElem1 foo=”x” bar=”y”>some text</ChildElem1>
<ChildElem2>
<Value1>some text</Value1>
<Value2>some text</Value2>
</ChildElem2>
</MyElem1>
What it means:
At runtime, an un-typed element can have any combination of attributes, sub-elements, or character data.
Why this is a problem:
The accelerators generate classes and properties that match the type definitions in the schema. The content of an un-typed element is ambiguous. Without any concrete type information, there is no way for the accelerator to determine what properties to generate for a given element.
If Process Commander needs to generate a property for an un-typed element, it will create a property of type Text
. If the un-typed element may occur more than once, Process Commander creates a value list property of type Text
.
What to do:
To use these properties at runtime, a concrete type must be substituted for the un-typed value, either in the XML data being received, or the clipboard page data being sent. With SOAP connectors, there is currently some degree of runtime type resolution, but there are a number of circumstances that could prevent inbound or outbound data mapping to fail.
For these reasons, the best thing to do is to edit the source XSD file and modify the element declaration. Set the value of the "type" attribute to a fully-qualified concrete type that defines the data to be sent or received. Then import the XSD file again.
Problem: Element or attribute wildcard components
What to look for:
Complex types that use the <xs:any> or <xs:anyAttribute> tags in their content model
Examples:
XSD Definition of MyElem1:
<!-- element that can contain any sub-element content -->
<xs:element name="MyElem1">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded">
</xs:sequence>
</xs:complexType>
</xs:element>
Legal instances of MyElem1:
<MyElem1>
<SomeValue foo=”x” bar=”y”>some text</SomeValue>
<SomeOtherValue>
<Value1>some text</Value1>
<Value2>some text</Value2>
</SomeOtherValue>
</MyElem1>
XSD Definition of MyElem2:
<!-- element that can contain any attribute defined by this schema -->
<xs:element name="MyElem2">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:anyAttribute namespace="#targetNamespace"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Legal instances of MyElem2:
<MyElem2 ns:foo=”x” ns:bar=”y”>some text</MyElem2>
What it means:
The complex element being defined may contain any combination of sub-elements or attributes.
Why this is a problem:
The accelerators generate properties for all declared attributes or sub-elements of a given complex type. The use of these tags means that anything will do. But stating that anything will do is the equivalent of saying nothing at all. In this case, the accelerator does not generate any properties because it has no information about what properties to create.
Without properties to map to, XML parse rules discard data that it can’t map. Without properties to map from, a XML stream rules will likely not contain the data they should and outgoing messages could trigger error or validation messages from the external system.
What to do:
Edit the source XSD and modify the definitions by replacing the any or anyAttribute wildcard components with concrete element or attribute declaration components that match the content that is to be sent or received. Then import the XSD file again.
Problem: Element substitution groups
What to look for:
Elements that are declared with the substitutionGroup attribute.
Example:
XSD Definition of ItemList:
<!-- list of substitutable product elements -->
<xs:element name="ItemList">
<xs:complexType>
<xs:sequence>
<xs:element ref="Product" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Product" type="ProductType"/>
<xs:complexType name="ProductType">
<xs:sequence>
<xs:element name="Number" type="xs:integer"/>
<xs:element name="Name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Shirt" substitutionGroup="Product">
<xs:complexType>
<xs:complexContent>
<xs:extension base="ProductType">
<xs:sequence>
<xs:element name="Size" type="xs:integer"/>
<xs:element name="Color" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="Hat" substitutionGroup="Product">
<xs:complexType>
<xs:complexContent>
<xs:extension base="ProductType">
<xs:sequence>
<xs:element name="Size" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
Legal instances of ItemList:
<ItemList>
<Product>
<Number>999</Number>
<Name>Special Seasonal</Name>
</Product>
<Shirt>
<Number>557</Number>
<Name>Short-Sleeved Linen Blouse</Name>
<Size>10</Size>
<Color>Blue</Color>
</Shirt>
<Hat>
<Number>563</Number>
<Name>Ten-Gallon Hat</Name>
<Size>L</Size>
</Hat>
</ItemList>
What it means:
These elements can be substituted for other elements in an XML instance at runtime.
Why this is a problem:
The accelerators create properties for all declared sub-elements of a complex type definition. However, there is no way for Process Commander to define a class rule in such a way as to say “Class Foo has a property A of type X, except that A may actually be a property called B of type Y, or a property called C of type Z”.
See the ItemList example, above. In this case, the accelerator would create a page-list property called Product for class ItemList. However, at runtime, Process Commander would map only Product elements, and would discard Shirt or Hat instances.
What to do:
Edit the XSD or WSDL and replace any references to substitution group elements with choice groups that include all of the substitution elements. Then import the XSD again.
Problem: Nested choice and sequence groups.
What to look for:
Complex types that contain <xs:sequence> tags inside of <xs:choice> tags, or <xs:choice> tags inside of <xs:sequence> tags.
Example:
XSD Definition of MyElem1:
<!-- sequence groups nested in a choice group -->
<xs:element name=”MyElem1”>
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name=”Child1” type=”xs:string”/>
<xs:element name=”Child2” type=”xs:string”/>
</xs:sequence>
<xs:sequence>
<xs:element name=”Child2” type=”xs:string”/>
<xs:element name=”Child3” type=”xs:string”/>
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
Legal instances of MyElem1:
<MyElem1>
<Child1>foo</Child1>
<Child2>bar</Child2>
</MyElem1>
<MyElem1>
<Child2>foo</Child2>
<Child3>bar</Child3>
</MyElem1>
Illegal instances of MyElem1:
<MyElem1>
<Child1>foo</Child1>
<Child3>bar</Child3>
</MyElem1>
<MyElem1>
<Child1>foo</Child1>
<Child2>bar</Child2>
<Child3>xxx</Child3>
</MyElem1>
XSD Definition of MyElem2:
<!-- choice groups nested in a sequence group -->
<xs:element name=”MyElem2”>
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element name=”Child1” type=”xs:string”/>
<xs:element name=”Child3” type=”xs:string”/>
</xs:choice>
<xs:choice>
<xs:element name=”Child2” type=”xs:string”/>
<xs:element name=”Child3” type=”xs:string”/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
Legal instances of MyElem2:
<MyElem2>
<Child1>foo</Child1>
<Child2>bar</Child2>
</MyElem2>
<MyElem2>
<Child1>foo</Child1>
<Child3>bar</Child3>
</MyElem2>
<MyElem2>
<Child3>foo</Child3>
<Child3>bar</Child3>
</MyElem2>
Illegal instances of MyElem2:
<MyElem2>
<Child2>foo</Child2>
<Child3>bar</Child3>
</MyElem2>
<MyElem2>
<Child1>foo</Child1>
<Child2>bar</Child2>
<Child3>xxx</Child3>
</MyElem2>
What it means:
The content model declares that some groupings of sub-elements are legal, while others are not.
Why this is a problem
Process Commander has no concept of property ordering – that is, sequence – or properties being interchangeable – that is, choice. When the two concepts are intermingled in a single type definition, Process Commander cannot determine the intent of the schema.
In the examples, above, notice that one of the legal instances of MyElem2 contains two Child3 sub-elements. If the accelerator encountered the element described in the example, it would generate only one single-value property for the Child3 element. Then, when one of those instances of MyElem2 was sent to Process Commander, the generated parse XML rule would discard one of the two Child3 values.
The most likely error to occur in this case, however, is an XML validation error. Using the rules that were generated for these type definitions, it would be easy for Process Commander to generate any of the illegal instances shown below in the examples. If the remote system is validating the XML that it receives from Process Commander against the original schema definition, it is likely that the data Process Commander sends will result in validation errors.
What to do:
Consider editing the source XSD and modifying the complex type definitions that contain nested choice or sequence groups to contain a single choice or sequence group. However, if this possibility constrains the content definition in such a way that the external application would no longer be able to consume the data, you must manually fix the data model in Process Commander. In that case, edit the XML stream rules so they allow for conditional formatting of XML data.
Problem: Repeating content groups
What to look for:
Sequence, choice, or group tags that have a maxOccurs attribute whose value is greater that one.
Example:
XSD Definition of MyElem1:
<!-- repeating sequence of elements -->
<xs:element name=”MyElem1”>
<xs:complexType>
<xs:sequence maxOccurs=”3”>
<xs:element name=”Child1” type=”xs:string”/>
<xs:element name=”Child2” type=”xs:string”/>
</xs:sequence>
</xs:complexType>
</xs:element>
Legal instances of MyElem1:
<MyElem1>
<Child1>foo</Child1>
<Child2>bar</Child2>
</MyElem1>
<MyElem1>
<Child1>val1</Child1>
<Child2>val2</Child2>
<Child1>val3</Child1>
<Child2>val4</Child2>
<Child1>val5</Child1>
<Child2>val6</Child2>
</MyElem1>
XSD Definition of MyElem2:
<!-- repeating interchangable elements -->
<xs:element name=”MyElem2”>
<xs:complexType>
<xs:choice minOccurs=”0” maxOccurs=”unbounded”>
<xs:element name=”Child1” type=”xs:string”/>
<xs:element name=”Child2” type=”xs:string”/>
</xs:choice>
</xs:complexType>
</xs:element>
Legal instances of MyElem2:
<MyElem2/>
<MyElem2>
<Child2>val1</Child2>
<Child2>val2</Child2>
<Child1>val3</Child1>
<Child2>val4</Child2>
<Child1>val5</Child1>
<Child1>val6</Child1>
<Child1>val7</Child1>
<Child2>val8</Child2>
</MyElem2>
XSD Definition of MyElem3:
<!-- repeating element group -->
<xs:element name=”MyElem3”>
<xs:complexType>
<xs:group ref="ns1:MyGroup" minOccurs=”0” maxOccurs=”unbounded”/>
</xs:complexType>
</xs:element>
<xs:group name=”MyGroup”>
<xs:sequence>
<xs:element name=”Child1” type=”xs:string”/>
<xs:element name=”Child2” type=”xs:string”/>
</xs:sequence>
</xs:group>
Legal instances of MyElem3:
<MyElem3/>
<MyElem3>
<Child1>val1</Child1>
<Child2>val2</Child2>
<Child1>val3</Child1>
<Child2>val4</Child2>
</MyElem3>
What it means:
A set of sub-elements may be repeated within an instance
Why this is a problem:
If the maxOccurs attribute is set for the specific sub-elements, there is no problem. If the maxOccurs attribute is set for a group of sub-elements, that is, it is set in the sequence, choice, or group component, Process Commander ignores it.
See the examples, above. In each example, the Child1 and Child2 element declarations will result in single value properties being generated, even though these elements may appear multiple times within an instance. This means that incoming data may be discarded by an XML parse rule because it can’t map parts of it, and outbound data generated by the generated XML stream rule may not pass validation because it is incomplete.
What to do:
Consider modifying the XSD file and setting the maxOccurs attribute on the individual elements, not on the sequence, choice, or group component. Then import the XSD file again. However, if the external application expects the entire sequence to be repeated rather than just the individual elements, you must manually modify the data model in Process Commander instead. Edit the XML stream rules so they can contain conditional content.
Problem: Complex type extensions
What to look for:
A complex type definition that contains the component <xs:extension>.
Examples:
XSD Definition of RentalCar:
<!-- element with a sub-element with a type that may be extended -->
<xs:element name=”RentalCar”>
<xs:complexType>
<xs:sequence>
<xs:element name=”PrimaryDriver” type=”ns1:Customer”/>
<xs:element name=”AdditionalDriver” type=”ns1:Customer” minOccurs=”0”/>
</xs:sequence>
</xs:complexType>
<xs:element>
<xs:complexType name=”Customer”>
<xs:sequence>
<xs:element name=”Name” type=”xs:string”/>
</xs:sequence>
</xs:complexType>
<xs:complexType name=”PreferredCustomer”>
<xs:complexContent>
<xs:extension base="ns1:Customer">
<xs:sequence>
<xs:element name=”RewardPoints” type=”xs:int”/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Legal instances of RentalCar:
<RentalCar>
<PrimaryDriver xsi:type="ns1:PreferredCustomer">
<Name>Jane Smith</Name>
<RewardPoints>4000</RewardPoints>
</PrimaryDriver>
<AdditionalDriver>
<Name>John Smith</Name>
</AdditionalDriver>
</RentalCar>
What it means:
At runtime, a base type might be overridden by an instance of an extended type.
Why this is a problem:
The accelerators do not currently generate XML parse and stream rules that support this behavior (that is, polymorphism).
What to do:
Complex type extensions allow you to optionally override a base type with a derived type. For outbound data mapping, you can do this by replacing an embedded page of a given class with a page of a class that inherits from the declared page class of the property. For inbound data mapping, you can modify your data mapping steps to accommodate the derived types.
If a class, parse, and stream rule were generated for the derived complex type, modify the parse and stream rules to include content from the base type.
If a class was generated for the derived complex type but parse and stream rules were not, copy the parse and stream rules from the base class into the derived class. Then, modify them to include content from the derived type.
If a class was not generated for the derived type, run the accelerator again and select the derived type from the list of global type definitions.
Problem: Abstract base types
What to look for:
Complex types that use the abstract=”true” attribute
Examples:
XSD Definition of ProductList:
<!-- list of elements that must use type substitution at runtime -->
<xs:element name=”ProductList”>
<xs:complexType>
<xs:sequence>
<xs:element name=”Product” type=”ns1:ProductType” minOccurs=”0” maxOccurs=”unbounded”/>
</xs:sequence>
</xs:complexType>
<xs:element>
<xs:complexType name=”ProductType” abstract="true">
<xs:sequence>
<xs:element name=”Name” type=”xs:string”/>
</xs:sequence>
</xs:complexType>
<xs:complexType name=”ShirtType”>
<xs:complexContent>
<xs:extension base="ns1:ProductType">
<xs:sequence>
<xs:element name=”Size” type=”xs:string”/>
<xs:element name=”Color” type=”xs:string”/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Legal instances of ProductList:
<ProductList>
<Product xsi:type="ns1:ShirtType">
<Name>Men’s Dress Shirt</Name>
<Size>XL</Size>
<Color>blue</Color>
</Product>
<Product xsi:type="ns1:ShirtType">
<Name>Women’s Knit Shirt</Name>
<Size>M</Size>
<Color>green</Color>
</Product>
</ProductList>
Illegal instance of ProductList:
<ProductList>
<Product>
<Name>Men’s Dress Shirt</Name>
</Product>
<Product>
<Name>Women’s Knit Shirt</Name>
</Product>
</ProductList>
What it means:
Elements defined using this type must be overridden at runtime with derived, non-abstract types.
Why this is a problem:
Instances of abstract types cannot be sent in an XML stream. The Process Commander application must override the content of the embedded page and page list properties with pages that belong to concrete classes derived from the abstract base type. Otherwise the resulting XML is invalid.
What to do:
This problem is solved in the same way as is the complex type extensions problem, except that you must override the base type in the outbound data mapping (it is not optional).
Problem: Mixed content
What to look for:
A complex element or type that uses the “mixed” attribute. Mixed content is used for mixing text with tagged element values. HTML is a common example of mixed content.
Example:
XSD Definition of MyElem1:
<!-- element with free-form markup content -->
<xs:element name=”MyElem1”>
<xs:complexType mixed="true">
<xs:sequence>
<xs:any minOccurs=”0” maxOccurs=”unbounded” processContents=”lax”/>
</xs:sequence>
</xs:complexType>
</xs:element>
Legal instances of MyElem1:
<MyElem1>This is an example of <b>mixed</b> content</MyElem1>
What it means:
Any text markup is allowed between the opening and closing tags for the element.
Why this is a problem:
First, see the example, above. In the example, it is unclear how data should be mapped to or from properties on a clipboard page. Additionally, when using elements with mixed content, you cannot treat the content the same way that you would treat regular text.
What to do:
First, replace the xs:complexType declaration with the xs:string type in the source XSD and use the accelerator to import it again. Then, to include HTML or markup in the XML, be sure to XML encode the tags embedded in the text. That way, the content can be treated as simple text.
Problem: Scalar value constraints
What to look for:
Elements or attributes that reference custom <xs:simpleType> definitions
Examples:
XSD Definition of ShirtSize:
<xs:element name=”ShirtSize” type=”ns1:ShirtSizeType”/><xs:simpleType name=”ShirtSizeType”>
<xs:restriction base=”xs:token”>
<xs:enumeration value=”XS”/>
<xs:enumeration value=”S”/>
<xs:enumeration value=”M”/>
<xs:enumeration value=”L”/>
<xs:enumeration value=”XL”/>
<xs:enumeration value=”XXL”/>
</xs:restriction>
</xs:simpleType>
Legal instances of ShirtSize:
<ShirtSize>M</ShirtSize>
<ShirtSize>XXL</ShirtSize>
Illegal instances of ShirtSize:
<ShirtSize>Small</ShirtSize>
<ShirtSize>XXXL</ShirtSize>
XSD Definition of DressSize:
<!-- scalar element with a custom type -->
<xs:element name=”DressSize” type=”ns1:DressSizeType”/>
<xs:simpleType name=”DressSizeType”>
<xs:restriction base=”xs:integer”>
<xs:minInclusive value=”2”/>
<xs:maxInclusive value=”18”/>
<xs:pattern value=”\d{1,2}”/>
</xs:restriction>
</xs:simpleType>
Legal instances of DressSize:
<DressSize>12</DressSize>
<DressSize>5</DressSize>
Illegal instances of DressSize:
<DressSize>1</DressSize>
<DressSize>XL</DressSize>
What it means:
The value of a scalar element or attribute will have special format constraints on its content. That is, the definition uses simple content restrictions.
Why this is a problem:
As described in Simple Content Restrictions, the only two simple type restriction components that have an effect on rule generation are enumeration and maxLength declarations (known as “facets”). Enumeration values are stored as Local List values on the Table Edit tab of generated property rules, and maxLength values are stored as the maximum length of generated Text or Identifier properties.
All other simple type restriction facets, as well as union and list types are ignored by the accelerators when they generate the data model.
What to do:
To enforce the constraints specified by the schema at runtime, create validation rules for the generated property rules to ensure compliance with the schema definitions.