How to convert and combine multiple XML files into one

I want your help to turn some XML into new using XSLT. I have code for selecting multiple XML and applying XSLT on them.

My problem is with XSLT, where I want to convert these shop1.xml shop2xml .. to allshops.xml. This is not an easy task for those who know how to work with XSLT, because there are only 2-3 changes.

Below you can find structures for a better understanding. Thank you very much.

shop1.xml

<shop> <products> <product id="189"> <title></title> <description></description> <price></price> <image></image> <url></url> <category id="61"></category> </product> </products> </shop> 

shop2.xml

 <shop> <products> <product id="182"> <title></title> <description></description> <price></price> <image></image> <url></url> <category id="62"></category> </product> </products> </shop> 

shop3.xml // it has direct products as root, and id is already present

 <products> <product> <id>123</id> <title></title> <description></description> <price></price> <image></image> <url></url> <category id="62"></category> </product> </products> 

paths.xml it is used from php code to get multiple xml files

 <?xml version="1.0" encoding="utf-8"?> <files> <file>shop1.xml</file> <file>shop2.xml</file> <file>shop3.xml</file> </files> 

allshops.xml

 <products> //removed the store,shop and products stays as root <product> <id>the product attribute id</id> //new element, with value the product id="" <title></title> <description></description> <price></price> <image></image> <url></url> <category></category> //removed the attribute id <shopid></shopid> //new element, will be blank for now </product> <product> </product> . . . </products> 
+4
source share
1 answer

As requested, a pure XSLT solution is used here, which combines external files using the XSLT 1.0 document() function.

Note:


[XSLT 1.0]

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:include href="identity.xsl"/> <xsl:template match="/*"> <products> <xsl:for-each select="file"> <xsl:apply-templates select="document(.)/*//product"> <xsl:with-param name="file" select="."/> </xsl:apply-templates> </xsl:for-each> </products> </xsl:template> <xsl:template match="product"> <xsl:param name="file"/> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:if test="not(id)"> <id><xsl:value-of select="@id"/></id> </xsl:if> <xsl:apply-templates select="node()"/> <shopid><xsl:value-of select="$file"/></shopid> </xsl:copy> </xsl:template> <xsl:template match="category/@id | product/@id"/> </xsl:stylesheet> 

When applied to the paths.xml file provided in the question, it creates:

 <products> <product> <id>189</id> <title/> <description/> <price/> <image/> <url/> <category/> <shopid>shop1.xml</shopid> </product> <product> <id>1418</id> <title/> <description/> <price/> <image/> <url/> <category/> <shopid>shop1.xml</shopid> </product> <product> <id>182</id> <title/> <description/> <price/> <image/> <url/> <category/> <shopid>shop2.xml</shopid> </product> <product> <id>118</id> <title/> <description/> <price/> <image/> <url/> <category/> <shopid>shop2.xml</shopid> </product> </products> 
+6
source

All Articles