2

I have 2 XML files with data about same items, that are kept on client and server. Some of the data are the same, some attributes/sub-elements are different on client compared to server.

Client data look like this (with more attributes that are irrelevant to the comparison):

<item id="1" create_dttm="05/28/2010 12:00:00 AM" name="Correct_Name">
        <text1>sample</text1>
        <icon>iconurl</icon>        
</item>

Server data look like this (with more attributes and possible sub-elements):

<item type="4" id="1" name="mispelled_name">
</item> 

Because matching for the items is done via the ID in our code, people that did data entry for the server.xml were not very careful with the names, leaving in typos or placeholder names. This does not cause bugs, however i would prefer to be on the safe side and make sure all the misspelled entries in server.xml to be replaced by correct names from the client.xml (those are double checked and are all correct)

Is it possible to run some script/code/xslt stylesheet to replace the names in the server.xml with the names from the client.xml?

I am not very familiar with stylesheets and not sure where to begin with coding something like that

Basically i want it to look like this:

Read client.xml
Read server.xml

For each item in client.xml, read attributes "id" and "name"
find item with same "id" in server.xml
replace "name" in server.xml with value from client.xml for the item with that "id"

Thank you for any help you can provide

1 Answer 1

2

You could make use of the document function here, to look up information from a second document (in your case 'client.xml') when applying the XSLT to server.xml

For example, you could define a variable like, to contain all the item elements in client.xml

<xsl:variable name="client" select="document('client.xml')//item" />

Then, to replace the @name attributes in server.xml, you could create a template to match the attributes, and output the values from client.xml instead.

<xsl:template match="item/@name">
    <xsl:attribute name="name">
        <xsl:value-of select="$client[@id=current()/../@id]/@name" />
    </xsl:attribute>
</xsl:template>

Here is the full XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:param name="clientXml" select="'client.xml'" />

    <xsl:variable name="client" select="document($clientXml)//item" />

    <xsl:template match="item/@name">
        <xsl:attribute name="name">
            <xsl:value-of select="$client[@id=current()/../@id]/@name" />
        </xsl:attribute>
    </xsl:template>

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

When applied to your sample client.xml and server.xml documents, the following is output

<item type="4" id="1" name="Correct_Name"></item>

Note that I have parameterised the name of the 'client.xml' document, as this would allow you to use the XSLT on differently named documents if required. You would just have to pass the name of the second XML file as a parameter.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.