Изменение пространства имен xpath-default-name в исходных файлах XML - PullRequest
3 голосов
/ 07 декабря 2009

У меня есть набор файлов XML, которые я обрабатываю с помощью преобразования XSL. У них есть пространство имен по умолчанию, поэтому мое XSL-преобразование должно содержать объявление:

XPath-умолчанию-имена = "урна: CZ-Р-IS-вав-XML-NS: данные-1.2.2"

Проблема заключается в том, что это значение время от времени меняется, и мое преобразование внезапно перестает работать, пока я не посмотрю на пример из нового файла, не извлеку этот идентификатор пространства имен и не помещу его в преобразование, в результате чего преобразование перестает работать для старые файлы. Есть ли способ передать это как параметр или установить его как-нибудь во время выполнения? Я пробовал синтаксис параметров, который я искал в различных руководствах, но ни один из них не работал для этого конкретного использования.

Я искал всевозможные форумы и нашел ссылки на независимое от пространства имен кодирование XSL, но не выяснил, как это сделать. Книга Яна Уильямса «XSLT and Xpath» гласит, что пространство имен по умолчанию должно быть объявлено, или вы ничего не получите в выходном потоке, как это работало для меня. Но я действительно не хочу регулярно менять это вручную, я хочу дать пользователю то, что будет работать, не требуя от меня постоянного внимания.

Единственный на 100% надежный способ, который я изобрел на данный момент, - это использование стандартного языка программирования, чтобы открыть исходный код XML и преобразование XSL в виде текстовых файлов, извлечь URI из источника XML, вставить его в преобразование XSL, закрыть оба файла, а затем, наконец, запустить фактическое преобразование. Это работает, но невероятно глупо, по крайней мере, на мой вкус. Как мне лучше справиться с изменением пространств имен по умолчанию?

Пит

Ответы [ 2 ]

5 голосов
/ 07 декабря 2009

Значение xpath-default-namespace должно быть статическим URI, поэтому вам придется предварительно обработать таблицу стилей, если вы хотите, чтобы она изменялась. Один из способов сделать это - использовать XSLT. Примените следующую таблицу мета-стилей к основной таблице стилей каждый раз, а затем вызовите предварительно обработанный результат.

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- Pass in the new namespace URI as a stylesheet parameter -->
  <xsl:param name="new-uri" required="yes"/>

  <!-- By default, copy everything as is -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- But update the value of @xpath-default-namespace -->
  <xsl:template match="@xpath-default-namespace">
    <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
      <xsl:value-of select="$new-uri"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

Это немного странный случай использования, потому что пространства имен на самом деле не были такими динамичными. Они были разработаны, чтобы квалифицировать имена, то есть составлять часть имени. Когда вы смотрите на это таким образом, динамические пространства имен не имеют большого смысла. Представьте себе базу данных, чьи имена таблиц и полей произвольно меняются время от времени, вынуждая вас переписывать все ваши SQL-скрипты, чтобы не отставать от изменений. Вот что это сродни.

0 голосов
/ 07 декабря 2009

Вы пытались определить параметр таблицы стилей <xsl:param name="xpdn"/> и использовать его в объявлении таблицы стилей или объявлении шаблона верхнего уровня, как в

<xsl:template match="...." xpath-default-namespace="$xpdn">

Я не могу найти в спецификации ничего, что говорит, что это не сработает (но я не могу попробовать это прямо сейчас).

...