本文介绍了创建 XSLT 转换以展平 multiRef 编码的 SOAP 消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

输入是一个 mutliRef 编码的 SOAP 消息/文档.你怎么用XSLT 扁平化 multiRefs.Multiref 节点可以被引用使用多次,并且自己递归地引用其他 multiRef节点.

Input is a mutliRef encoded SOAP message/document. How do you useXSLT to flatten multiRefs. Multiref nodes can be referenced usedmultiple times, and themselves recursively reference other multiRefnodes.

唯一可以安全引用的结构部分是multiRef 元素和@id 和@href 属性.其他元素或命名空间可能会改变.

The only pieces of the structure that are safe to refer to, aremultiRef elements and @id and @href attributes. Other elements ornamespaces could change.

示例输入消息是:

<?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>

更新:在上面的例子中,从逻辑上讲,应该发生的是:

Update:In the example above, logically, what should happen is:

在第一次传递时,getAccountDTOResponse 包含@href="#id0",因此该元素被替换为所有具有@id="id0" 的子 multiRef 元素,但除外.

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.

在第二遍时,应该发现@href="#id1",并且ID 元素应该替换为@id="id1" 元素的内容.

On the second pass, @href="#id1" should be discovered, and ID element should be replaced with contents of element with @id="id1".

输出中不应存在 multiRef 元素.如果在整个 multiRef 混乱中涉及到 @id 或 @href 属性,则输出中不应存在任何属性.

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.

推荐答案

Alex,我没有完全匹配您的输出,但这里是您如何通过 href 解析文档的方法.

Alex, I'm not matching your output completely but here is how you can resolve your document by 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>

我认为可以轻松定制此方法以满足您的需求.我想概述所提供的样式表在 @hrefs 上运行并且不考虑任何元素名称.因此可以灵活使用,无需注意引用元素名称.但是,所有引用都应命名为 multiRefs,但这也可以轻松自定义.

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 named multiRefs but this can be easily customized too.

这篇关于创建 XSLT 转换以展平 multiRef 编码的 SOAP 消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 09:43