使用xslt合并xmls - 基于元素值

时间:2015-05-19 22:21:18

标签: xml xslt

XML1:具有Stationid和端口号

 <?xml version="1.0" encoding="UTF-8"?>
  <getPublicStationsResponse xmlns:ns1="urn:dictionary:com.chargepoint.webservices" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <stationData>
    <stationID>1:86013</stationID>
    <Port>
       <portNumber>1</portNumber>
       <stationName>EMBASSY TROY / EMBASSY SUITE 1</stationName>
       <Level>L2</Level>
    </Port>
    <Port>
       <portNumber>2</portNumber>
       <stationName>EMBASSY TROY / EMBASSY SUITE 1</stationName>
       <Level>L2</Level>
    </Port>
   </stationData>
   <stationData>
   <stationID>1:2155</stationID>
    <Port>
       <portNumber>1</portNumber>
       <stationName>MAGNA ECAR / TROY VISITOR 01</stationName>
       <Level>L1</Level>
     </Port>
      <Port>
       <portNumber>2</portNumber>
       <stationName>MAGNA ECAR / TROY VISITOR 01</stationName>
        <Level>L2</Level>
      </Port>
    </stationData>
 </getPublicStationsResponse>

XML 2:此xmls具有station id,portnumber和portstatus

     <?xml version="1.0" encoding="UTF-8"?>
 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:dp="http://www.datapower.com/schemas/management" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 <soapenv:Body>
  <ns1:getPublicStationStatusResponse xmlns:ns1="urn:dictionary:com.chargepoint.webservices">

     <stationStatusData>
        <stationID>1:86013</stationID>
        <Port>
           <portNumber>1</portNumber>
           <Status>AVAILABLE</Status>

        </Port>
        <Port>
           <portNumber>2</portNumber>
           <Status>AVAILABLE</Status>

        </Port>
     </stationStatusData>
     <stationStatusData>
        <stationID>1:2155</stationID>
        <Port>
           <portNumber>1</portNumber>
           <Status>AVAILABLE</Status>

        </Port>
        <Port>
           <portNumber>2</portNumber>
           <Status>AVAILABLE</Status>

        </Port>
     </stationStatusData>
  </ns1:getPublicStationStatusResponse>

这里:

1匹配xml1和2中的stationID 2对于每个端口 - 匹配portsnumber并从第二个xml获取Status,将状态追加到第一个xml。

 OUTPUT:

        <?xml version="1.0" encoding="UTF-8"?>
    <getPublicStationsResponse xmlns:ns1="urn:dictionary:com.chargepoint.webservices" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <stationData>
        <stationID>1:86013</stationID>
    <Port>
        <portNumber>1</portNumber>
        <Status>AVAILABLE</Status> 
        <stationName>EMBASSY TROY / EMBASSY SUITE 1</stationName>
        <Level>L2</Level>
  </Port>
  <Port>
     <portNumber>2</portNumber>
     <Status>AVAILABLE</Status> 
     <stationName>EMBASSY TROY / EMBASSY SUITE 1</stationName>
     <Level>L2</Level>
  </Port>
</stationData>
<stationData>
  <stationID>1:2155</stationID>
  <Port>
     <portNumber>1</portNumber>
     <Status>AVAILABLE</Status> 
     <stationName>MAGNA ECAR / TROY VISITOR 01</stationName>
     <Level>L1</Level>

  </Port>
  <Port>
     <portNumber>2</portNumber>
     <Status>AVAILABLE</Status> 
     <stationName>MAGNA ECAR / TROY VISITOR 01</stationName>
     <Level>L2</Level>
   </Port>
  </stationData>
</getPublicStationsResponse>

1 个答案:

答案 0 :(得分:0)

假设您正在处理第一个XML文档并将路径作为参数传递给第二个文件,您可以这样做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="lookup-path" select="'file2.xml'" />
<xsl:key name="status" match="Port" use="concat(../stationID, '|', portNumber)" />

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

<xsl:template match="Port">
    <xsl:copy>
        <xsl:apply-templates/>
        <xsl:variable name="key" select="concat(../stationID, '|', portNumber)" />
        <!-- switch context to lookup document -->
        <xsl:for-each select="document($lookup-path)">
            <Status>
                <xsl:value-of select="key('status', $key)/Status"/>
            </Status>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>