需要帮助xslt 1.0分组以映射样式表

时间:2014-02-03 19:14:28

标签: xml xslt mapping grouping

使用xslt 1.0样式表来映射地址服务。我查找了Muenchian方法的一些示例,用于在xslt 1.0中进行分组,但我仍然对xsl:key和嵌套xsl:for-each循环感到困惑。

我只关心InputAddress节点集。作为父InputAddress节点的一部分,可能有多个(但不总是)ValidateRequest节点集,因此我需要循环遍历InputAddress的所有迭代,然后执行到相关元素的映射。

source xml

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v1="blah" xmlns:v3="blah2">
<soap:Header/>
<soap:Body>
    <v1:validate>
        <ValidateRequest>
            <!--One or more repetitions:-->
            <InputAddress>
                <v3:City>Redmond</v3:City>
                <v3:Territory>
                    <v3:Name>Washington</v3:Name>
                    <FIPSStateAlphaCode>WA</FIPSStateAlphaCode>
                </v3:Territory>
                <v3:PostalCode>98007</v3:PostalCode>
                <v3:Country>
                    <!--Zero or more repetitions:-->
                    <v3:Name>US</v3:Name>
                </v3:Country>
                <v3:FullAddress>123 main street</v3:FullAddress>
                <v3:FullAddress>Ste 200</v3:FullAddress>
            </InputAddress>
            <InputAddress>
                <v3:City>Seattle</v3:City>
                <v3:Territory>
                    <v3:Name>Washington</v3:Name>
                    <FIPSStateAlphaCode>WA</FIPSStateAlphaCode>
                </v3:Territory>
                <v3:PostalCode>98103</v3:PostalCode>
                <v3:Country>
                    <!--Zero or more repetitions:-->
                    <v3:Name>US</v3:Name>
                </v3:Country>
                <v3:FullAddress>987 1st street</v3:FullAddress>
            </InputAddress>
        </ValidateRequest>
    </v1:validate>
</soap:Body>

预期结果

    <soap:Body>
    <wsdl:WS_MDM_Address_ValidationRequest>
        <wsdl:WS_MDM_Address_ValidationRequestElement>
            <wsdl:Address_Line1>123 main street</wsdl:Address_Line1>
            <wsdl:Address_Line2>Ste 200</wsdl:Address_Line2>
            <wsdl:City>Redmond</wsdl:City>
            <wsdl:State>WA</wsdl:State>
            <wsdl:Postal_Code>98007</wsdl:Postal_Code>
            <wsdl:Country>US</wsdl:Country>
        </wsdl:WS_MDM_Address_ValidationRequestElement>
        <wsdl:WS_MDM_Address_ValidationRequestElement>
            <wsdl:Address_Line1>987 1st Street</wsdl:Address_Line1>
            <wsdl:City>Seattle</wsdl:City>
            <wsdl:State>WA</wsdl:State>
            <wsdl:Postal_Code>98103</wsdl:Postal_Code>
            <wsdl:Country>US</wsdl:Country>
        </wsdl:WS_MDM_Address_ValidationRequestElement>
    </wsdl:WS_MDM_Address_ValidationRequest>
</soap:Body> 

和我的命名模板snipet在xsl:choose(未显示)之后:

<xsl:key name="AddressDoctor" match="v3:FullAddress" use="//v3:FullAddress" />
<xsl:variable name="address" select="/*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='validate']/ValidateRequest/InputAddress"/>

<xsl:template name="addressdoctor">
    <soap:Envelope>
        <soap:Header>
            <xsl:copy-of select="/*[local-name()='Envelope']/*[local-name()='Header']/*"/>
        </soap:Header>
        <soap:Body>
            <wsdl:WS_MDM_Address_ValidationRequest>

            <xsl:for-each select="key('AddressDoctor', '.')">
                <wsdl:WS_MDM_Address_ValidationRequestElement>
                    <xsl:for-each select="[not($FullAddress = preceding::text()=$FullAddress)]">
                        <xsl:element name="wsdl:{concat('Address_Line',position())}">
                            <xsl:value-of select="."/>
                        </xsl:element>
                    </xsl:for-each>
                    <wsdl:City>
                    <xsl:for-each select="$address/*[local-name()='City']">
                        <xsl:value-of select="$address/*[local-name()='City']"/>
                    </xsl:for-each>
                    </wsdl:City>
                    <wsdl:State>
                        <xsl:value-of select="$address/*[local-name()='Territory']/*[local-name()='FIPSStateAlphaCode']"/>
                    </wsdl:State>
                    <wsdl:Postal_Code>
                        <xsl:value-of select="$address/*[local-name()='PostalCode']"/>
                    </wsdl:Postal_Code>
                    <wsdl:Country>
                        <xsl:value-of select="$address/*[local-name()='Country']/*[local-name()='Name']"/>
                    </wsdl:Country>
                </wsdl:WS_MDM_Address_ValidationRequestElement>
                </xsl:for-each>
            </wsdl:WS_MDM_Address_ValidationRequest>
        </soap:Body>
    </soap:Envelope>
</xsl:template>

1 个答案:

答案 0 :(得分:0)

根据您提供的输入XML,我没有看到需要任何类型的分组。考虑到您正在使用XSLT 1.0,这是一件好事,因为分组可能有点难以正确。您可以从简单的身份模板开始,然后覆盖一些元素以显示您要查找的输出。

这是XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:v1="blah" xmlns:v3="blah2" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <xsl:output method="xml" indent="yes" />

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ValidateRequest">
    <wsdl:WS_MDM_Address_ValidationRequest>
      <xsl:apply-templates/>
    </wsdl:WS_MDM_Address_ValidationRequest>
  </xsl:template>

  <xsl:template match="InputAddress">
    <wsdl:WS_MDM_Address_ValidationRequestElement>
      <wsdl:Address_Line1>
        <xsl:value-of select="v3:FullAddress[1]"/>
      </wsdl:Address_Line1>
      <xsl:if test="v3:FullAddress[2]">
        <wsdl:Address_Line2>
          <xsl:value-of select="v3:FullAddress[2]"/>
        </wsdl:Address_Line2>
      </xsl:if>
      <wsdl:City>
        <xsl:value-of select="v3:City"/>
      </wsdl:City>
      <wsdl:State>
        <xsl:value-of select="v3:Territory/FIPSStateAlphaCode"/>
      </wsdl:State>
      <wsdl:Postal_Code>
        <xsl:value-of select="v3:PostalCode"/>
      </wsdl:Postal_Code>
      <wsdl:Country>
        <xsl:value-of select="v3:Country/v3:Name"/>
      </wsdl:Country>
    </wsdl:WS_MDM_Address_ValidationRequestElement>
  </xsl:template>

  <xsl:template match="v1:validate">
    <xsl:apply-templates/>
  </xsl:template>

</xsl:stylesheet>

这将根据您提供的示例生成您要查找的输出。