【问题标题】:XSLT Transformation from SOAPSOAP 的 XSLT 转换
【发布时间】:2015-10-18 06:12:28
【问题描述】:

我有一个如下所示的传入 SOAP 消息:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns3:GetImageResponse xmlns="urn:webservice/server/mobile/shoebox/types/v1/CustomImage" xmlns:ns2="urn:webservice/server/mobile/shoebox/types/v1/common/ShoeboxCommonArtifacts" xmlns:ns3="urn:webservice/server/mobile/shoebox/types/v1/Image" xmlns:ns4="urn:webservice/server/mobile/shoebox/types/v1/common/exceptions" xmlns:ns5="urn:webservice/server/mobile/shoebox/types/v1/GetThumbnailImage">
<ns3:returnCode>105</ns3:returnCode>
<ns3:errorText>Invalid Participant code/id.</ns3:errorText>
<ns3:shoeboxImage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</ns3:GetImageResponse>
</soap:Body>
</soap:Envelope>


需要转换为另一个简单的 XML,如下所示:(约束 - SOAP 信封的 BODY 下的根元素(例如,如果“GetImageResponse”到来,我们需要在输出 XML 中构造“GetImage”元素)并且它不是恒定的是任意元素所以需要根据 BODY 下的根元素来构造 XML,Ex 如下所示)

<?xml version="1.0" encoding="UTF-8"?>
<tns:GetImage xmlns:bons1="http://highmark.com/rbssvc/messages/common" xmlns:tns="http://www.example.org/GetImageResponseMessage/" xmlns:tns1="http://www.example.org/GetImageResponse/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/GetImageResponseMessage/ ../xsd/GetImageResponseMessage.xsd ">

 <payload>
    <returnCode>returnCode</returnCode>
    <errorText>errorText</errorText>
    <imageData>MA==</imageData>
  </payload>

我在 XSLT 下面使用这个来转换:

<xsl:stylesheet extension-element-prefixes="dp" exclude-result-prefixes="dp regex" version="1.0" xmlns:dp="http://www.datapower.com/extensions" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:regex="http://exslt.org/regular-expressions">
   <xsl:template match="/">
      <GetImage>
         <xsl:element name="{'Payload'}">
            <xsl:copy-of select="/*/*[local-name()='Body']/*[local-name()='GetImageResponse']/*"/>
         </xsl:element>
      </GetImage>
   </xsl:template>
</xsl:stylesheet>

但我没有得到上面显示的所需 XML 输出

我得到的输出是:

<GetImageResponse>
   <Payload>
      <ns3:returnCode xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns5="urn:webservice/server/mobile/shoebox/types/v1/GetThumbnailImage" xmlns:ns4="urn:webservice/server/mobile/shoebox/types/v1/common/exceptions" xmlns:ns3="urn:webservice/server/mobile/shoebox/types/v1/Image" xmlns:ns2="urn:webservice/server/mobile/shoebox/types/v1/common/ShoeboxCommonArtifacts" xmlns="urn:webservice/server/mobile/shoebox/types/v1/CustomImage">105</ns3:returnCode>
      <ns3:errorText xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns5="urn:webservice/server/mobile/shoebox/types/v1/GetThumbnailImage" xmlns:ns4="urn:webservice/server/mobile/shoebox/types/v1/common/exceptions" xmlns:ns3="urn:webservice/server/mobile/shoebox/types/v1/Image" xmlns:ns2="urn:webservice/server/mobile/shoebox/types/v1/common/ShoeboxCommonArtifacts" xmlns="urn:webservice/server/mobile/shoebox/types/v1/CustomImage">Invalid Participant code/id.</ns3:errorText>
      <ns3:shoeboxImage xsi:nil="true" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns5="urn:webservice/server/mobile/shoebox/types/v1/GetThumbnailImage" xmlns:ns4="urn:webservice/server/mobile/shoebox/types/v1/common/exceptions" xmlns:ns3="urn:webservice/server/mobile/shoebox/types/v1/Image" xmlns:ns2="urn:webservice/server/mobile/shoebox/types/v1/common/ShoeboxCommonArtifacts" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:webservice/server/mobile/shoebox/types/v1/CustomImage"/>
   </Payload>
</GetImageResponse>

问题就在这里,就像我无法复制传入soap消息的名称空间一样元素“GetImageResponse”和一些额外的命名空间也将用于元素“payload”。enter code here

知道如何将 SOAP 消息转换为所需的 XML 输出。

感谢快速回复。

问候 Rj

【问题讨论】:

标签: xslt


【解决方案1】:

好吧,多余的 xmlns 声明是视觉噪音,但在功能上不是问题。但是,您可以通过确保在生成的结果的根元素上设置必要的 xmlns 声明来解决此问题。在您的情况下,这是:&lt;GetImage&gt;

您会注意到,在您的样式表中,GetImage 元素位于包含 XSLT 样式表的文档的默认命名空间中,这也未指定。

例子:

<!-- 
     namespace GetImage and 
     set up additional namespace mapping for ns5 prefix
     for any copied elements which may be injected 
 -->
<tns:GetImage xmlns:tns="tns-uri" xmlns:ns5="ns5-uri">
    <!-- more stuff here -->
</tns:GetImage>

接下来您的&lt;xsl:element name="{'Payload'}"&gt; 调用也不会注入命名空间。您可以使用 xsl:element 的 namespace 属性将生成的元素与所需的命名空间 (URI) 相关联,也可以使用 name 属性中的语法 {prefix}:{local-name} 并添加适当的 xmlns:prefix 声明。

例子:

<xsl:element name="foo" namespace="bar"/>
<!-- needs xmlns:ns declaration -->
<xsl:element name="ns:foo"/>
<!--  substantially the same, using 'expressions' instead of 'literals' -->
<xsl:element name="{$nsPrefix}:{local-name()}">

【讨论】:

    【解决方案2】:

    您的问题并不完全清楚。我认为你想做这样的事情:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns3="urn:webservice/server/mobile/shoebox/types/v1/Image" 
    xmlns:my="http://www.example.com/my"
    exclude-result-prefixes="soap ns3 my">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <my:ns-holder xmlns:bons1="http://highmark.com/rbssvc/messages/common" xmlns:tns1="http://www.example.org/GetImageResponse/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/GetImageResponseMessage/ ../xsd/GetImageResponseMessage.xsd "/>
    
    <xsl:template match="/soap:Envelope/soap:Body/*">
        <xsl:element name="tns:{local-name()}" xmlns:tns="http://www.example.org/GetImageResponseMessage/">
            <xsl:copy-of select="document('')/xsl:stylesheet/my:ns-holder/namespace::*"/>
            <payload>
                <returnCode>
                    <xsl:value-of select="ns3:returnCode" />
                </returnCode>
                <errorText>
                    <xsl:value-of select="ns3:errorText" />
                </errorText>
                <imageData>MA==</imageData>
            </payload>
        </xsl:element>
    </xsl:template>
    
    </xsl:stylesheet>
    

    这是做什么的:

    1. 创建一个根元素,其本地名称与 soap:Body 的子节点,为其分配一个 tns: 前缀并绑定 "http://www.example.org/GetImageResponseMessage/' 的前缀 命名空间。请注意,这是假设只有一个这样的孩子。

    2. 为上面的根元素添加一堆命名空间。请注意,这些 命名空间实际上并没有在结果中使用 - 因此是 完全多余。

    3. 创建有效负载及其值节点。请注意,您不能使用 xsl:copy here,因为这也会复制原始节点的 命名空间(本例中为ns3)。

    应用于您的输入示例,这里的结果将是:

    <?xml version="1.0" encoding="UTF-8"?>
    <tns:GetImageResponse xmlns:tns="http://www.example.org/GetImageResponseMessage/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns3="urn:webservice/server/mobile/shoebox/types/v1/Image" xmlns:my="http://www.example.com/my" xmlns:bons1="http://highmark.com/rbssvc/messages/common" xmlns:tns1="http://www.example.org/GetImageResponse/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <payload>
          <returnCode>105</returnCode>
          <errorText>Invalid Participant code/id.</errorText>
          <imageData>MA==</imageData>
       </payload>
    </tns:GetImageResponse>
    

    我不明白:

    • 究竟应该如何将GetImageResponse 转换为GetImage
    • imageData 值 ("MA==​​") 应该来自哪里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      相关资源
      最近更新 更多