Its me again, but this time i have a real problem…
I have one XML, and i have to transform it in another XML by using a filter of another XML
File_in.xml:
<?xml version="1.0" encoding="ISO-8859-15"?>
<root>
<item>
<server>001023541</server>
<name>P1</name>
<desc>Production</desc>
<status>1</status>
<ram>1024</ram>
<hdd>8 To</hdd>
</item>
<item>
<server>201012345</server>
<name>P2</name>
<desc>Production</desc>
<status>4</status>
<ram>2048</ram>
<hdd>8 To</hdd>
</item>
<item>
<server>120332416</server>
<name>P1</name>
<desc>Production</desc>
<status>2</status>
<ram>8196</ram>
<hdd>8 To</hdd>
</item>
</root>
And another XML:
filter.xml
<?xml version="1.0" encoding="ISO-8859-15"?>
<Filtre>
<Bloc5>
<Part1>
<EAN>001023541</EAN>
<EAN>012356549</EAN>
<EAN>012356559</EAN>
<EAN>012356569</EAN>
</Part1>
<Part2>
<EAN>201012345</EAN>
<EAN>201012346</EAN>
<EAN>201012347</EAN>
</Part2>
</Bloc5>
</Filtre>
If /root/item/server matches with an element of /Filtre/Bloc5/Part1/EAN, i replace
<item>
<server>001023541</server>
<name>P1</name>
<desc>Production</desc>
<status>1</status>
<ram>1024</ram>
<hdd>8 To</hdd>
</item>
by
<item>
<server>MAIN</server>
<status>PRODUCTION</status>
</item>
otherwise if /root/item/server matches with an element of /Filtre/Bloc5/Part2/EAN, i replace
<item>
<server>201012345</server>
<name>P2</name>
<desc>Production</desc>
<status>4</status>
<ram>2048</ram>
<hdd>8 To</hdd>
</item>
by
<item>
<server>BACKUP</server>
<status>STOPPED</status>
</item>
and the other are automatically replaced like:
<item>
<server>120332416</server>
<name>P1</name>
<desc>Production</desc>
<status>2</status>
<ram>8196</ram>
<hdd>8 To</hdd>
</item>
by
<item>
<name>OFFLINE</name>
<desc>Production</desc>
</item>
I get the name of the XML (used to filter) by this way:
<!-- filter settings -->
<xsl:param name="filter_xml" />
<xsl:variable name="filter" select="document('$filter_xml')" />
And there is my code :
<xsl:for-each select="root/item">
<xsl:choose>
<xsl:when test="index-of(($filter/Filtre/Bloc5/Part1/EAN), ./server)">
<item>
<server>MAIN</server>
<status>PRODUCTION</status>
</item>
</xsl:when>
<xsl:when test="index-of(($filter/Filtre/Bloc5/Part2/EAN), ./server)" >
<item>
<server>BACKUP</server>
<status>STOPPED</status>
</item>
</xsl:when >
<xsl:otherwise>
<item>
<name>OFFLINE</name>
<desc>Production</desc>
</item>
</xsl:otherwise>
</xsl:for-each>
But this does not work…
A much cleaner, simpler and efficient solution is to use template matching instead of tortuous branching. I am assuming XSLT 2.0 because you did not tag your question with the XSLT version number, but if you need XSLT 1.0, then adjustments can easily be made.
Update: Icing on the cake
Thanks for your acceptance. As icing on the cake, you could also replace the first two item templates with this ONE more generic and extensible template. But it’s debatable whether it is more simpler or more complex.
Alternative generic item template (only works for XSLT 2.0) …