Question

I'm trying to convert a XLIFF file back into a proper xml file using this code:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="//body">
      <xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
        <file source-language="en-US" datatype="plaintext" target-language="de">
            <body>
                <xsl:for-each select="//trans-unit">
                    <xsl:element name="string">
                        <xsl:attribute name="name"><xsl:value-of select="@id"/></xsl:attribute>
                        <xsl:value-of select="target"/>
                    </xsl:element>      
                </xsl:for-each>
            </body>
        </file>
    </xliff>
    </xsl:template>
</xsl:stylesheet>

But all it get as a return are the strings enclosed in the <source> and <target> tags. I'm doing something terribly wrong or i'm missing some special tag to do so?

I was able to successfully create an XLIFF file using a simple XSLT script but I'm struggling to convert it back.

Any ideas are appreciated.

Regards, Thomas

Here is an example of the xliff file

<?xml version='1.0' encoding='utf-8'?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
  <file source-language="en" datatype="plaintext" target-language="de">
    <body>
      <trans-unit xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:space="preserve" approved="yes" id="firstrun_textview_language_array_names1">
        <source>English</source>
        <target>Englisch</target>
      </trans-unit>
      <trans-unit xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:space="preserve" approved="no" id="firstrun_textview_language_array_names2">
        <source>Chinese (traditional)</source>
        <target>i dont know</target>
      </trans-unit>
    </body>
  </file>
</xliff>
Was it helpful?

Solution

The issue here is with namespaces. In your XLIFF sample you have defined a default namespace

<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" version="1.1">

This means all the elements under this will belong to this namespace (unless overridden with another namespace).

However, you have not declared this namespace in your XSLT, and so wherever it is looking for elements, it is looking for elements in NO namespace, and finding the cupboard is bare. In this case, the built-in templates kick-in which end up just outputing all the text values.

To solve this, first add a declaration of the XLIFF namespace that matches the XML

<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"    
   xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" 
   exclude-result-prefixes="xliff">

Then, use this prefix when looking for elements. For example

<xsl:template match="//xliff:body">

Here is the full XSLT. Note there is no real need to use xsl:element with a static element name, just output the element directly. (Also note the use of Attribute Value Templates instead of using xsl:attribute).

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.1" exclude-result-prefixes="xliff">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="//xliff:body">
        <xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
            <file source-language="en-US" datatype="plaintext" target-language="de">
                <body>
                   <xsl:for-each select="//xliff:trans-unit">
                      <string name="{@id}">
                         <xsl:value-of select="xliff:target"/>
                      </string>      
                   </xsl:for-each>
                </body>
            </file>
        </xliff>
    </xsl:template>
</xsl:stylesheet>

When applied to your XML, the following is output

<xliff version="1.1" xmlns="urn:oasis:names:tc:xliff:document:1.1">
   <file source-language="en-US" datatype="plaintext" target-language="de">
      <body>
        <string name="firstrun_textview_language_array_names1">Englisch</string>
        <string name="firstrun_textview_language_array_names2">i dont know</string>
     </body>
   </file>
</xliff>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top