How to create document from Xml string

I would like to convert an xml string (it was built from a byte array with an external tool.

My document and my input line were generated from the same xsd I read the line with pub.string:stringToBytes

then I get the XmlNode frompub.xml:xmlStringToXMLNode

This part works well.

I would create a document after that, call it Doc. I'm calling pub.xml:xmlNodeToDocument

. But the returned document is not of the correct type. I mean all the data is correct with the correct name, but when I tried to map some data against another document, it never works.

I know this is not clear, sorry about that. So, in detail, I have a simple xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <xs:complexType name="EtdDaCisIUpdParty">
    <xs:sequence>
      <xs:element name="wUpdatetsMax">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:maxLength value="15"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element name="wTpsnEtendu" type="WTpsnEtendu"/>
      <xs:element name="wTpsnExt" type="WTpsnExt" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="WTpsnEtendu">
    <xs:sequence>
      <xs:element name="Id" type="xs:string"></xs:element>
      <xs:element name="Name" type="xs:string"></xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="WTpsnExt">
    <xs:sequence>
      <xs:element name="key" type="xs:string"></xs:element>
      <xs:element name="value" type="xs:string"></xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="EtdDaCisIUpdParty" type="EtdDaCisIUpdParty" />

</xs:schema>

      

And the corresponding xml line corresponding to this xsd:

<?xml version="1.0" encoding="utf-8"?>
<mstns:EtdDaCisIUpdParty  xmlns:mstns="http://tempuri.org/XMLSchema.xsd" >
    <mstns:wUpdatetsMax>40</mstns:wUpdatetsMax> 
    <mstns:wTpsnEtendu>
        <mstns:Id>13</mstns:Id>
        <mstns:Name>Test</mstns:Name>
    </mstns:wTpsnEtendu>
    <mstns:wTpsnExt>
        <mstns:key>1</mstns:key>
        <mstns:value>one</mstns:value>
    </mstns:wTpsnExt>
    <mstns:wTpsnExt>
        <mstns:key>2</mstns:key>
        <mstns:value>something</mstns:value>
    </mstns:wTpsnExt>
    <mstns:wTpsnExt>
        <mstns:key>3</mstns:key>
        <mstns:value>nothing</mstns:value>
    </mstns:wTpsnExt>
</mstns:EtdDaCisIUpdParty>

      

Document generated with the same xsd: enter image description here

Then I have a stream service that converts the xml string to document

enter image description here

Seems to work, but it doesn't. If I add a simple map, it never gets processed:

enter image description here

The resulting pipeline never contains the last card value. After using debug mode, I realize that the resulting document is pub.xml:xmlStringToXMLNode

not the same type as my document.

enter image description here

The Id

line is missing in the pipeline.

What is wrong with my understanding and my example?

+3


source to share


1 answer


The answer to your question lies in the subtle differences in variable structure mstns:EtdDaCisIUpdParty

between your 2nd and 3rd screenshots:

Your second screenshot shows the data structure according to the doc link you used when you declared a variable that is a representation of the project time structure (as you expect the data structure will look like):

- mstns:EtdDaCisIUpdParty
  - mstns:wUpdatetsMax
  - mstns:wTpsnEtendu
  - ...

      

Compared to the third screenshot which shows the actual data structure at runtime:

- mstns:EtdDaCisIUpdParty
  - @version
  - @encoding
  - mstns:EtdDaCisIUpdParty
     - mstns:wUpdatetsMax
     - mstns:wTpsnEtendu
     - ...

      

Notice the extra layer in the runtime structure that contains the XML prologue attributes @version

and a @encoding

named child document mstns:EtdDaCisIUpdParty

that represents the root node of your XML document.

Although you have specified your pipeline variable mstns:EtdDaCisUpdParty

as a document reference, this is irrelevant at runtime and has no effect. Document links allow webMethods Designer to show you the data structure as you expect in a graphical interface, allowing you to work with it at design time. However, links to documentation are not executed at runtime.



At run time, since you are mapped from the top level document

to mstns:EtdDaCisUpdParty

, it has the same structure as the one document

, which is different from the document reference you used during design time. This is why your map step is not working. The variable mstns:EtdDaCisIUpdParty/mstns:wTpsnEtendu/mstns:Id

does not actually exist in the pipeline at run time, and at one level deeper in the structure: mstns:EtdDaCisIUpdParty/mstns:EtdDaCisIUpdParty/mstns:wTpsnEtendu/mstns:Id

.

You can fix their service flow, comparing it to the next level in the structure: document/mstns:EtdDaCisIUpdParty

mstns:EtdDaCisIUpdParty

, rather than document

mstns:EtdDaCisIUpdParty

.

Since it document

is a dynamic structure (its structure is only known at runtime, since it depends on the XML it parses), you need to manually create an IData document named mstns:EtdDaCisIUpdParty

as a child under the Call Service Exitdocument

in the pipeline , and then type:pub.xml:xmlNodeToDocument

  • Right click on the Service Outletdocument

    in the pipeline (not the Pipeline Out on the right),
  • Insert new document variable
  • Name it mstns:EtdDaCisIUpdParty

  • Open mstns:EtdDaCisIUpdParty

    in the pipeline Service output to your variable mstns:EtdDaCisIUpdParty

    in Pipeline Out .

Additionally, I would recommend that you set the following input parameters when invoked pub.xml:xmlNodeToDocument

so that all XML documents are parsed sequentially:

  • Set makeArrays

    to false

    because it is necessary if you supply a value fordocumentTypeName

  • Set nsDecls/mstns

    to http://tempuri.org/XMLSchema.xsd

    so that all XML documents regardless of the namespace prefix used are parsed sequentially (prefixes other than mstns

    will still be represented as mstns:fieldname

    namespaced fields ; this will not happen unless you declare namespaces in the parameter nsDecls

    )
  • Set documentTypeName

    the document reference you used to declare the variable mstns:EtdDaCisIUpdParty

    so that the XML elements with are maxOccurs > 1

    parsed sequentially (always parsed as an array, even if the element in question happened only once in the XML)

And to protect your service from unexpected / unsupported XML documents, you should probably call pub.schema:validate

to make sure the XML is well-formed and valid against the XSD you listed above or similar.

+2


source







All Articles