0

I am running the following transformation:

java -jar saxon9.jar -it:main -xsl:my.xsl dir="ca-ES"

The "ca-ES" contains XLIFF files which have the following root element:

<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cba="http://www.softcon.de/XML-schema/de.softcon.cba.itembuilder.xliff-supplement"
       version="1.1"
       xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 xliff-core-1.1.xsd">

The transformation uses identical files from a secondary input folder and generates as many structurally identical files as found in the input folder.

If I remove the first namespace (i.e. xmlns="urn:oasis:names:tc:xliff:document:1.1") from the root (i.e. xliff), then the transformation works like a charm. However, if I keep it, then it doesn't work.

The part that is not working is the template that matches source in the primary input file and replaces it with the source from the secondary input file):

<xsl:copy-of select="key('ref', ../@id, doc($secondary-input))/source" />

By not working I mean that the source from the primary input file is in the output rather than the expected source node from the secondary input. So it seems the namespace is getting in the way of the matching.

Looking for solutions I have tried adding the xpath-default-namespace attribute on the document element of the stylesheet:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xpath-default-namespace="urn:oasis:names:tc:xliff:document:1.1"
    version="2.0">

but then the source node from the primary input is kept in the output (that is, it's not replaced with the one from the secondary input).

I have also tried adding this prefix and then using it in the stylesheet to match nodes (e.g. match="xlf:source"), but then there is no source node at all in the output:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xlf="urn:oasis:names:tc:xliff:document:1.1"
    version="2.0">

I'll be grateful for some tips.

I'm using XSLT 2.0 and saxonb9-1-0-8j.

UPDATE

Adding one primary input file sample (named ca-ES_blabla.xlf, taken from the folder ca-ES):

<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cba="http://www.softcon.de/XML-schema/de.softcon.cba.itembuilder.xliff-supplement" version="1.1" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 xliff-core-1.1.xsd">
  <file datatype="html" original="project.properties" source-language="ca">
    <body>
      <trans-unit id="MDSD_0" xml:space="default">
        <source>Gestiona les adreces d'interès</source>
        <target>Gestiona les adreces d'interès</target>
        <context-group name="era">
          <context context-type="x-property-id">bookmarkHeaderText</context>
        </context-group>
      </trans-unit>
      <trans-unit id="7" xml:space="default">
        <source>&lt;b&gt;Sempre rebrà un avís quan arribi a un punt a partir del qual no pugui tornar enrere.&lt;/b&gt;&lt;br /&gt;</source>
        <target>&lt;b&gt;Sempre rebrà un avís quan arribi a un punt a partir del qual no pugui tornar enrere.&lt;/b&gt;&lt;br /&gt;</target>
        <prop-group name="item_description">
          <prop prop-type="x-inquiry-nr">4</prop>
          <prop prop-type="x-type">question</prop>
        </prop-group>
      </trans-unit>
    </body>
  </file>
<!-- the xliff document might contain several <file> nodes -->
</xliff>

one secondary input file sample (named en-GB_blabla.xlf, taken from the folder en-GB):

<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cba="http://www.softcon.de/XML-schema/de.softcon.cba.itembuilder.xliff-supplement" version="1.1" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 xliff-core-1.1.xsd">
  <file datatype="html" original="project.properties" source-language="en-GB">
    <body>
      <trans-unit id="MDSD_0" xml:space="default">
        <source>Manage your bookmarks</source>
        <target>Manage your bookmarks</target>
        <context-group name="era">
          <context context-type="x-property-id">bookmarkHeaderText</context>
        </context-group>
      </trans-unit>
      <trans-unit id="7" xml:space="default">
        <source>&lt;b&gt;You will always receive a warning before reaching a point where you cannot go back.&lt;/b&gt;&lt;br /&gt;</source>
        <target>&lt;b&gt;You will always receive a warning before reaching a point where you cannot go back.&lt;/b&gt;&lt;br /&gt;</target>
        <prop-group name="item_description">
          <prop prop-type="x-inquiry-nr">4</prop>
          <prop prop-type="x-type">question</prop>
        </prop-group>
      </trans-unit>
    </body>
  </file>
<!-- the xliff document might contain several <file> nodes -->
</xliff>

and the stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xpath-default-namespace="urn:oasis:names:tc:xliff:document:1‌​.1"
    version="2.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
    <xsl:strip-space elements="*"/>

    <!-- run as: 
    $> java -jar saxon9.jar -it:main -xsl:this_stylesheet.xsl dir="xx-XX"      -->

    <!-- this captures the folder parameter given in the call -->  
    <xsl:param name="dir" select="dir" />

    <!-- this template iterates through the files in the input folder --> 
    <xsl:template name="main">
        <xsl:variable name="input-files" select="concat($dir, '?select=*.xlf')" />
        <xsl:apply-templates select="collection($input-files)"/>
    </xsl:template>

    <!-- this template defines the name of the output folder and files -->
    <xsl:template match="/">
        <xsl:variable name="output-name" select="replace(
            tokenize(document-uri(/), '/')[last()], 
            '(.+)\.xlf', 
            '$1_bilingual.xlf'
            )"/>
        <xsl:result-document href="{$dir}_output/{$output-name}">
            <xsl:apply-templates/>
        </xsl:result-document>
    </xsl:template>

    <!-- this template fetches the source from the English files --> 
    <xsl:key name="ref" match="trans-unit" use="@id"/> 
    <xsl:template match="source">
        <xsl:variable name="input-uri" select="document-uri(/)" />
        <!-- <xsl:message><xsl:value-of select="$input-uri" /></xsl:message> -->
        <xsl:variable name="secondary-input" select="replace($input-uri, $dir, 'en-GB')"/>
        <xsl:copy-of select="key('ref', ../@id, doc($secondary-input))/source" />
    </xsl:template>

    <!-- this part generates the output --> 
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
msoutopico
  • 357
  • 3
  • 15
  • Do both input files (primary pulled in with collection and secondary pulled in with doc) use exactly the same namespace? – Martin Honnen Jun 19 '17 at 19:56
  • Hi Martin :) Yes, primary and secondary input files are identical except for the content of the `source` node. – msoutopico Jun 19 '17 at 20:02
  • You might want to add the stylesheet and two input samples to allow us to debug it if you can't find the problem yourself, I think it must be a namespace difference between the two files. – Martin Honnen Jun 19 '17 at 20:06
  • I'm pretty sure there's no difference between in the root nodes between the two input files, I have just compared a few with Oxygen's Diff Files. The only differences are in the content of the source elements and the target-language values. I'm adding them and the stylesheet in a minute to my question. – msoutopico Jun 19 '17 at 20:14
  • I agree those two XML documents use the same default namespace, that means the stylesheet from the earlier question can't work unless you add `xpath-default-namespace="urn:oasis:names:tc:xliff:document:1.1"` on the root of the stylesheet. I don't think the stylesheet posted in this question will compile at all, given then use of prefixes `match="xlf:trans-unit"` without declaring it. – Martin Honnen Jun 19 '17 at 20:35
  • Sorry, my fault. The `xlf` prefix was left from my early test with `xmlns:xlf="urn:oasis:names:tc:xliff:document:1.1"`, which didn't work either. I've just fixed it in the question. However, as I mentioned, adding the `xpath-default-namespace="urn:oasis:names:tc:xliff:document:1‌​.1"` doesn't make it work. – msoutopico Jun 19 '17 at 20:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/147131/discussion-between-msoutopico-and-martin-honnen). – msoutopico Jun 20 '17 at 08:15

1 Answers1

1

It seems to be a namespace problem, when I copy over the value "urn:oasis:names:tc:xliff:document:1.1" from the source to the stylesheet as xpath-default-namespace="urn:oasis:names:tc:xliff:document:1.1" the code works.

I am not sure which characters you have in your stylesheet code (oXygen asked me to enable some language support when pasting your code) but somehow the strings

"urn:oasis:names:tc:xliff:document:1.1"
"urn:oasis:names:tc:xliff:document:1‌​.1"

are not equal:

var s1 = "urn:oasis:names:tc:xliff:document:1.1";
var s2 = "urn:oasis:names:tc:xliff:document:1‌​.1";
document.writeln('<code>' + s1 + ' === ' + s2 + ' : ' + (s1 === s2) + '<\/code>');

It might be that the namespace in your stylesheet contains one or more https://en.wikipedia.org/wiki/Zero-width_non-joiner after the first digit 1.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • To be precise, my xmlns string had a ZERO WIDTH NON-JOINER (U+200C) and a ZERO WIDTH SPACE (U+200B). To be honest, I have no clue where they came from, but you are right, removing those extraneous characters the stylesheet works. Thanks, Martin. – msoutopico Jun 20 '17 at 11:45