Пространства имен, препятствующие преобразованию

Я запускаю следующее преобразование:

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

«ca-ES» содержит файлы XLIFF со следующим корневым элементом:

<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">

Преобразование использует идентичные файлы из вторичной входной папки и создает столько структурно идентичных файлов, сколько находится во входной папке.

Если я удалю первое пространство имен (т. е. xmlns="urn:oasis:names:tc:xliff:document:1.1") из корня (т. е. xliff), то преобразование работает как шарм. Однако, если я оставлю это, то это не сработает.

Часть, которая не работает, — это шаблон, который соответствует source в первичном входном файле и заменяет его на source из вторичного входного файла):

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

Под неработающим я подразумеваю, что source из основного входного файла находится на выходе, а не ожидаемый узел source из вторичного ввода. Таким образом, кажется, что пространство имен мешает сопоставлению.

В поисках решений я попытался добавить атрибут xpath-default-namespace в элемент документа таблицы стилей:

<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">

но тогда узел source из основного ввода сохраняется в выводе (то есть он не заменяется узлом из вторичного ввода).

Я также пытался добавить этот префикс, а затем использовать его в таблице стилей для сопоставления узлов (например, match="xlf:source"), но тогда в выводе вообще нет узла source:

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

Буду признателен за несколько советов.

Я использую XSLT 2.0 и saxonb9-1-0-8j.

ОБНОВЛЕНИЕ

Добавляем один образец основного входного файла (с именем ca-ES_blabla.xlf, взятый из папки 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>

один образец вторичного входного файла (с именем en-GB_blabla.xlf, взятый из папки 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>

и таблица стилей:

<?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>

person msoutopico    schedule 19.06.2017    source источник
comment
Используют ли оба входных файла (первичный, загруженный с коллекцией, и вторичный, извлеченный с помощью doc) одно и то же пространство имен?   -  person Martin Honnen    schedule 19.06.2017
comment
Привет, Мартин :) Да, первичный и вторичный входные файлы идентичны, за исключением содержимого узла source.   -  person msoutopico    schedule 19.06.2017
comment
Возможно, вы захотите добавить таблицу стилей и два входных образца, чтобы мы могли отладить ее, если вы не можете найти проблему самостоятельно, я думаю, что это должно быть различие в пространстве имен между двумя файлами.   -  person Martin Honnen    schedule 19.06.2017
comment
Я почти уверен, что нет никакой разницы между корневыми узлами между двумя входными файлами, я только что сравнил некоторые из них с файлами различий Oxygen. Единственные различия заключаются в содержании исходных элементов и значениях целевого языка. Я добавляю их и таблицу стилей через минуту к моему вопросу.   -  person msoutopico    schedule 19.06.2017
comment
Я согласен, что эти два XML-документа используют одно и то же пространство имен по умолчанию, что означает, что таблица стилей из предыдущего вопроса не может работать, если вы не добавите xpath-default-namespace="urn:oasis:names:tc:xliff:document:1.1" в корень таблицы стилей. Я не думаю, что таблица стилей, размещенная в этом вопросе, вообще скомпилируется, учитывая затем использование префиксов match="xlf:trans-unit" без объявления этого.   -  person Martin Honnen    schedule 19.06.2017
comment
Извините, моя вина. Префикс xlf остался от моего раннего теста с xmlns:xlf="urn:oasis:names:tc:xliff:document:1.1", который тоже не работал. Я только что исправил это в вопросе. Однако, как я уже упоминал, добавление xpath-default-namespace="urn:oasis:names:tc:xliff:document:1‌​.1" не заставит его работать.   -  person msoutopico    schedule 19.06.2017
comment
Давайте продолжим обсуждение в чате.   -  person msoutopico    schedule 20.06.2017


Ответы (1)


Кажется, это проблема пространства имен, когда я копирую значение "urn:oasis:names:tc:xliff:document:1.1" из источника в таблицу стилей, поскольку xpath-default-namespace="urn:oasis:names:tc:xliff:document:1.1" код работает.

Я не уверен, какие символы у вас есть в вашем коде таблицы стилей (oXygen попросил меня включить некоторую языковую поддержку при вставке вашего кода), но каким-то образом строки

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

не равны:

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>');

Возможно, пространство имен в вашей таблице стилей содержит один или несколько https://en.wikipedia.org/wiki/Zero-width_non-joiner после первой цифры 1.

person Martin Honnen    schedule 20.06.2017
comment
Чтобы быть точным, моя строка xmlns имела НУЛЕВУЮ ШИРИНУ НЕ-СОЕДИНИТЕЛЯ (U+200C) и НУЛЕВУЮ ШИРИНУ ПРОБЕЛ (U+200B). Честно говоря, я понятия не имею, откуда они взялись, но вы правы, удаляя эти посторонние символы, таблица стилей работает. Спасибо, Мартин. - person msoutopico; 20.06.2017