user555303
user555303

Reputation: 1374

XSLT to lookup values in one XML and replace in another XML file

One of the products we work with is able to output configuration information as XML, but, in that output file, instead of including actual host identifiers (names), they use a kind of GUID reference for each of the identifiers.

I have made an XML file that contains the "mapping" between the host identifiers GUIDs and the actual host identifiers(lookup), and I want to implement an XSLT that will go through the configuration file and replace all of the host identifier GUIDs with the host identifier names, which it would lookup from the other XML file I made (lookup.xml).

Here's what the lookup.xml file looks like:

<?xml version="1.0"?>
<hostids>

  <hostid name="e687903c-d185-4560-9117-c60f386b76c1">Agent</hostid>
  <hostid name="b9230962-13ca-4d23-abf8-d3cd1ca4dffc">test2</hostid>

</hostids>

and here is what the configuration file looks like (I ran the original file through some processing to get this):

<?xml version="1.0"?>
<resources>

  <resource><host>e687903c-d185-4560-9117-c60f386b76c1</host><url>/console/**</url></resource>
  <resource><host>b9230962-13ca-4d23-abf8-d3cd1ca4dffc</host><url>/ServiceByName</url></resource>

</resources>

and here is what the output should look like:

<?xml version="1.0"?>
<resources>

  <resource><host>Agent</host><url>/console/**</url></resource>
  <resource><host>test2</host><url>/ServiceByName</url></resource>

</resources>

I am working with xsltproc on a RedHat machine, which is XSLT 1.0, I think.

I have tried to get this working with several different example XSLTs that I found here, e.g.:

XSLT "replace" values with another file matching by attribute

but haven't been able to get any of them working.

Can anyone provide an XSLT 1.0 example that might be able to accomplish this?

P.S. This is another thread that had examples and the XSLT 1.0 examples wouldn't work for me. When I ran it (after modifying to match my element names, etc.), it looks like it just wrapped the entire original XML in .

How to use attribute values from another XML file as an element value selection in the current XML

Upvotes: 3

Views: 4163

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117140

Try it this way?

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="path-to-lookup" select="'lookup.xml'" />

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

<xsl:template match="host">
    <xsl:copy>
        <xsl:value-of select="document($path-to-lookup)/hostids/hostid[@name = current()]" />
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Or, if you prefer:

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="path-to-lookup" select="'lookup.xml'" />

<xsl:key name="host" match="hostid" use="@name" />

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

<xsl:template match="host">
    <xsl:copy>
        <xsl:variable name="host-id" select="." />
        <!-- switch context to lookup document in order to use key -->
        <xsl:for-each select="document($path-to-lookup)">
            <xsl:value-of select="key('host', $host-id)" />
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Upvotes: 4

Related Questions