Ввод - это сообщение / документ SOAP в кодировке MULTIREFКак вы используете XSLT для выравнивания multiRefs.На ссылки с несколькими ссылками можно ссылаться несколько раз, и сами они рекурсивно ссылаются на другие узлы с несколькими ссылками.
Единственными частями структуры, на которые можно безопасно ссылаться, являются элементы multiRef и атрибуты @id и @href.Другие элементы или пространства имен могут измениться.
Пример входного сообщения:
<?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>
Ожидаемый результат:
<?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>
Обновление: ВПример выше, логически, что должно произойти:
На первом проходе getAccountDTOResponse содержит @href = "# id0", так что этот элемент заменяется на все дочерние элементы multiRef с @ id = "id0",за исключением.
На втором проходе должно быть обнаружено @href = "# id1", а элемент ID должен быть заменен содержимым элемента с @ id = "id1".
В выводе не должно быть элементов multiRef.Никаких атрибутов @id или @href не должно быть в выходных данных, если они были вовлечены во весь этот беспорядок multiRef.
Алекс, я не полностью сопоставляю ваш вывод, но вот как вы можете разрешить документ с помощью hrefs.
Эта таблица стилей:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" > <xsl:key name="multiref-by-id" match="multiRef" use="@id"/> <xsl:template match="/"> <xsl:copy> <xsl:apply-templates select="@*|*"/> </xsl:copy> </xsl:template> <xsl:template match="*[starts-with(@href, '#')]"> <xsl:copy> <xsl:apply-templates select="@* | key('multiref-by-id', substring-after(@href, '#'))/@* | key('multiref-by-id', substring-after(@href, '#'))/node()"/> </xsl:copy> </xsl:template> <xsl:template match="@href[starts-with(., '#')] | multiRef[@id] | @soapenc:root"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
С учетом этого ввода:
<?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>
Дает следующий результат:
<?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 xmlns:ns1="http://www.example.com/pw/services/PWServices" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <getAccountDTOReturn id="id0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:Account"> <ID xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="urn:PWServices" id="id1" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:long"> 0 </ID> <accountNumber xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="urn:PWServices" xsi:type="soapenc:string"/> <accountType xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="urn:PWServices" xsi:type="soapenc:string"/> <clientData xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="urn:PWServices" xsi:type="soapenc:Array" xsi:nil="true"/> <name xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="urn:PWServices" xsi:type="soapenc:string"/> <parentRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="urn:PWServices" xsi:type="soapenc:string"/> </getAccountDTOReturn> </ns1:getAccountDTOResponse> </soapenv:Body> </soapenv:Envelope>
Я думаю, что это apporachможет быть легко настроен в соответствии с вашими потребностями.Я хотел бы подчеркнуть, что предоставленная таблица стилей работает на @hrefs и не учитывает имена элементов.Поэтому его можно использовать гибко, не обращая внимания на имена ссылающихся элементов.Однако все ссылки должны быть названы multiRef s, но это также может быть легко настроено.
@hrefs
multiRef
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"> <xsl:key name="kMultiRefById" match="multiRef" use="@id"/> <xsl:output method="xml"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="getAccountDTOReturn"> <xsl:variable name="vRefer" select="key('kMultiRefById',substring(@href,2))"/> <xsl:copy> <xsl:copy-of select="$vRefer/namespace::*"/> <xsl:apply-templates select="$vRefer/@*|$vRefer/node()"/> </xsl:copy> </xsl:template> <xsl:template match="multiRef|multiRef/@id|multiRef/@soapenc:root"/> </xsl:stylesheet>
Вывод:
<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 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"></ID> <accountNumber xsi:type="soapenc:string"></accountNumber> <accountType xsi:type="soapenc:string"></accountType> <clientData xsi:type="soapenc:Array" xsi:nil="true"></clientData> <name xsi:type="soapenc:string"></name> <parentRef xsi:type="soapenc:string"></parentRef> </getAccountDTOReturn> </ns1:getAccountDTOResponse> </soapenv:Body> </soapenv:Envelope>
Примечание : ключи для перекрестных ссылок.Правило идентичности.Пустые правила для зачистки. Копирование узлов пространств имен может быть недоступно для каждого процессора XSLT , хотя я знаю только о Mozilla TransforMiiX, в которой не реализована namespaces:: ось.
namespaces::