Applying templates multiple times based on string

2019-09-15 00:00发布

问题:

I have two XMLs

File1.xml It contains mapping for the IP need to copied multiple times and replacing the value with given.

    <baseNode>
            <internal ip="192.168.1.1">
                    <someOtherTags>withsome values which should not be changed</someOtherTags>
            </internal>
            <internal ip="192.168.1.2">
                    <someOtherTags>withsome more values which should not be changed</someOtherTags>
            </internal>
    </baseNode>

File2.xml

    <IPMappings>
    <sourceIP value="192.168.1.1">
            <replacement>10.66.33.22</replacement>
            <replacement>10.66.33.44</replacement>
    </sourceIP>
    <sourceIP value="192.168.1.2">
            <replacement>10.66.34.22</replacement>
            <replacement>10.66.34.44</replacement>
    </sourceIP>
    </IPMappings>

Resulting XML should be:

    <baseNode>
            <internal ip="10.66.33.22">
                    <someOtherTags>withsome values which should not be changed</someOtherTags>
            </internal>
            <internal ip="10.66.33.44">
                    <someOtherTags>withsome values which should not be changed</someOtherTags>
            </internal>

            <internal ip="10.66.34.22">
                    <someOtherTags>withsome more values which should not be changed</someOtherTags>
            </internal>
            <internal ip="10.66.34.44">
                    <someOtherTags>withsome more values which should not be changed</someOtherTags>
            </internal>
    </baseNode>

How can I use XSLT to do this?

回答1:

Here is my suggestion, the first document is the primary input document, the second document is passed in as a parameter:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

<xsl:param name="map-doc-url" select="'File2.xml'"/>
<xsl:variable name="map-doc" select="document($map-doc-url)"/>

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="ip" match="sourceIP" use="@value"/>

<xsl:template match="baseNode">
  <xsl:copy>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<xsl:template match="baseNode/internal">
  <xsl:variable name="this" select="."/>
  <xsl:for-each select="$map-doc">
    <xsl:apply-templates select="key('ip', $this/@ip)/replacement">
      <xsl:with-param name="internal" select="$this"/>
    </xsl:apply-templates>
  </xsl:for-each>
</xsl:template>

<xsl:template match="sourceIP/replacement">
  <xsl:param name="internal"/>
  <internal ip="{.}">
    <xsl:copy-of select="$internal/node()"/>
  </internal>
</xsl:template>

</xsl:stylesheet>

When I run above with Saxon 6.5.5 I get the following result:

<baseNode>
   <internal ip="10.66.33.22">
      <someOtherTags>withsome values which should not be changed</someOtherTags>
   </internal>
   <internal ip="10.66.33.44">
      <someOtherTags>withsome values which should not be changed</someOtherTags>
   </internal>
   <internal ip="10.66.34.22">
      <someOtherTags>withsome more values which should not be changed</someOtherTags>
   </internal>
   <internal ip="10.66.34.44">
      <someOtherTags>withsome more values which should not be changed</someOtherTags>
   </internal>
</baseNode>


标签: xml xslt