Search code examples
xmlxslt

XML per XLST to HTML from multiple files


I have to transform language specific XML-data into html. I can still change much of the setup and try to figure out how to do it best.

  • Products will have multiple xml-files (one per language, one per product), like Product1_EN.xml, Product1_DE.xml with a <PackageInsert lang="xy">-tag. (I split at this level so I can later select per URL).
  • There will be a Languages.xml-file with multiple <Language lang="xy">-tags.

This is my PackageInsert.xsl-file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html><head>
  </head><body>
    <xsl:for-each select="PackageInsert/Product">
      <h1>Product: <xsl:value-of select="Name"/></h1>
    </xsl:for-each>
  </body></html>
</xsl:template>
</xsl:stylesheet>

I have the following in my Product.xml-file:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="PackageInsert.xsl"?>
<PackageInsert lang="EN">
  <Product>
    <Name>AwesomeProduct<sup>®</sup></Name>
  </Product>
</PackageInsert>

This will translate to the following resulting html:

<html><head>
</head><body>
  <h1>Product: AwesomeProduct<sup>®</sup></h1>
</body></html>

I also have the following Languages.xml-file

<?xml version="1.0" encoding="UTF-8"?>
<Language lang="EN">
  <Product>Product</Product>
</Language>
<Language lang="DE">
  <Product>Produkt</Product>
</Language>

How can I bring them together, so that the currently hardcoded "Product"-part of the PackageInsert.xsl will come from the Languages.xml's \Language[lang="EN"]\Product-Entry, selected by the Product.xml's lang="EN"-attribute?

The expected result would be:

(pseudocode): if \PackageInsert[lang=="EN"]: {

<html><head>
</head><body>
  <h1>Product: AwesomeProduct<sup>®</sup></h1>
</body></html>

} elseif \PackageInsert[lang=="DE"]: {

<html><head>
</head><body>
  <h1>Produkt: AwesomeProduct<sup>®</sup></h1>
</body></html>

}


Solution

  • If your Languages.xml file contains a well-formed XML document, e.g.

    <Languages>
        <Language lang="EN">
            <Product>Product</Product>
        </Language>
        <Language lang="DE">
            <Product>Produkt</Product>
        </Language>
    </Languages>
    

    then you can get your expected result using:

    XSLT 1.0

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:template match="/PackageInsert">
        <html>
            <head/>
            <body>
                <h1>
                    <xsl:value-of select="document('Languages.xml')/Languages/Language[@lang=current()/@lang]/Product"/>
                    <xsl:text>: </xsl:text>
                    <xsl:copy-of select="Product/Name/node()"/>
                </h1>
            </body>
        </html>
    </xsl:template>
    
    </xsl:stylesheet>