Расположение схемы не копируется в XSLT с расширением Xalan Pipeline

я получил xml-файлы с "xsi:schemaLocation="location1 location2..." и много "xmlns:someNs". Хотя пространства имен будут скопированы в новый документ, schemaLocations нет, и я действительно не могу понять, почему они удаляются (все пространства имен и schemaLocations также находятся в моей таблице стилей).

Google говорит, что они будут удалены, если они не используются внутри документа или что-то в этом роде, и я должен добавить их сам, но, похоже, я не могу... Я использую конвейер xalan для передачи некоторых элементарных преобразований, и теперь Я пытаюсь добавить таблицу стилей в конец канала, чтобы снова добавить местоположения. это мой последний лист:

<xsl:template match="node()|@*">
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="/*">
    <xsl:attribute name="xsi:schemaLocation">
      <xsl:text>MYLOCATION</xsl:text>
    </xsl:attribute>

    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>

</xsl:template>

У меня было несколько вариантов с тегом элемента, окружающим без копии... лучшим результатом был удвоенный корневой элемент, один со schemaLocation и один со всеми пространствами имен, которые я действительно не могу понять.

Спасибо за любую помощь ;)

€: Кажется, что все мои отдельные таблицы стилей работают, кроме xalan pipe.

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:pipe="http://xml.apache.org/xalan/PipeDocument"
                extension-element-prefixes="pipe"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xsi:schemaLocation="someschema"
              >

  <xsl:param name="source"/>
  <xsl:param name="target"/>

  <!-- I think this block has no effect -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">

    <pipe:pipeDocument 
          source="{$source}"
          target="{$target}">
      <stylesheet href="sheet1.xsl"/>
      <stylesheet href="sheet2.xsl"/>
      <stylesheet href="sheet3.xsl"/>
    </pipe:pipeDocument>

  </xsl:template>

</xsl:stylesheet>

Xalan больше не вызывается с -IN и -OUT, и я думаю, что именно здесь я теряю свои местоположения, хотя я не понимаю, почему объявления xmlns все еще находятся в выводе. Каждый лист выполняет собственное преобразование идентичности и работает должным образом, если используется без канала.


person Dennis Ich    schedule 21.08.2012    source источник


Ответы (1)


Непонятно, почему атрибуты xsi:schemaLocation исчезают из вашего вывода, в основном потому, что вы не показали входные данные, выходные данные или шаблоны, которые создают этот вывод из этого ввода.

Шаблоны, которые вы показываете, не могут дать описанный вами результат, потому что они вообще не могут дать никакого результата. (Я подозреваю, что вы отредактировали их для краткости, что в целом хорошая идея, но вы зашли слишком далеко.) Шаблон, соответствующий /*, пытается записать атрибут без открытия какого-либо элемента в выводе; если бы какой-то вариант этого шаблона работал, но производил двойной корневой элемент, я бы предположил, что это потому, что у вас было два элемента xsl:copy в шаблоне.

Начните с рабочей версии таблицы стилей идентификации, и я ожидаю, что вы увидите, что в выводе появятся как объявления пространств имен, так и атрибуты xsi:schemaLocation.

Например, рассмотрим эту таблицу стилей (в которой отсутствуют шаблоны для комментариев и инструкции по обработке):

<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="1.0">
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Примените его к этому входу:

<test 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:foo="http://example.com/foo"
  xmlns:bar="http://example.com/bar"
  xsi:schemaLocation="http://example.com/foo foo.xsd
                      http://example.com/bar nss/bar.xsd">
  <data/>
</test>

Результат, который я получаю:

<test 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:foo="http://example.com/foo" 
  xmlns:bar="http://example.com/bar" 
  xsi:schemaLocation="
    http://example.com/foo foo.xsd
    http://example.com/bar nss/bar.xsd">
  <data/>
</test>

xsi:schemaLocation там. Есть объявления пространств имен. Если их нет в выводе вашей существующей таблицы стилей, то шаг за шагом измените этот рабочий код, чтобы он больше походил на ваш существующий код. В тот момент, когда атрибут расположения схемы и/или пространства имен перестают отображаться в выводе, вы обнаружили свою ошибку.

Если бы мне пришлось угадывать, я бы предположил, что атрибут xsi:schemaLocation удаляется вашей существующей таблицей стилей, потому что у вас нет шаблона, соответствующего ему во входных данных, и/или потому что шаблон, который соответствует его родителю, не включает xsl:apply-templates с select="@*".

person C. M. Sperberg-McQueen    schedule 21.08.2012
comment
Проблема, по-видимому, заключается в канале xalan, потому что все фрагменты сами по себе работают должным образом. Но как только они передаются, пространства имен уничтожаются. Я отредактирую это на свой первоначальный вопрос. - person Dennis Ich; 23.08.2012