Input is a mutliRef encoded SOAP message/document. How do you use XSLT to flatten multiRefs. Multiref nodes can be referenced used multiple times, and themselves recursively reference other multiRef nodes.
The only pieces of the structure that are safe to refer to, are multiRef elements and @id and @href attributes. Other elements or namespaces could change.
Sample input message is:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:getAccountDTOResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://www.example.com/pw/services/PWServices">
<getAccountDTOReturn href="#id0" />
</ns1:getAccountDTOResponse>
<multiRef id="id0" soapenc:root="0"
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="ns2:Account"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns2="urn:PWServices">
<ID href="#id1" />
<accountNumber xsi:type="soapenc:string"></accountNumber>
<accountType xsi:type="soapenc:string"></accountType>
<clientData xsi:type="soapenc:Array" xsi:nil="true" />
<name xsi:type="soapenc:string"></name>
<parentRef xsi:type="soapenc:string"></parentRef>
</multiRef>
<multiRef id="id1" soapenc:root="0"
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="xsd:long"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
0</multiRef>
</soapenv:Body>
</soapenv:Envelope>
Expected output is:
<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:getAccountDTOResponse xmlns:ns1="http://www.example.com/pw/services/PWServices"
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<getAccountDTOReturn xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns2="urn:PWServices"
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="ns2:Account">
<ns1:ID soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="xsd:long">0</ns1:ID>
<ns1:accountNumber xsi:type="soapenc:string" />
<ns1:accountType xsi:type="soapenc:string" />
<ns1:clientData xsi:type="soapenc:Array" xsi:nil="true" />
<ns1:name xsi:type="soapenc:string" />
<ns1:parentRef xsi:type="soapenc:string" />
</getAccountDTOReturn>
</ns1:getAccountDTOResponse>
</soapenv:Body>
</soapenv:Envelope>
Update: In the example above, logically, what should happen is:
On the first pass, getAccountDTOResponse contains @href="#id0", so that element is replaced with all the children multiRef element with @id="id0", with exception of.
On the second pass, @href="#id1" should be discovered, and ID element should be replaced with contents of element with @id="id1".
No multiRef elements should exists in the output. No attributes @id or @href should exists in output, if there were involved in this whole multiRef mess.
This stylesheet:
Output:
Note: Keys for cross references. Identity rule. Empty rules for stripping. Copying namespaces nodes might not be posible for every XSLT processor, although I only know about Mozilla's TransforMiiX wich doesn't have implemented
namespaces::
axis.Alex, I'm not matching your output completely but here is how you can resolve your document by hrefs.
This stylesheet:
Given this input:
Produces the following result:
I think that this apporach could be easily customized to fit your needs. I would like to outline that the provided stylesheet operates on
@hrefs
and does not take in account any element names. Therefore it can be used flexibly without paying attention to the referring element names. However all the reference should be namedmultiRef
s but this can be easily customized too.