2010-05-20 3 views
1

Я преобразовываю XML-схему с помощью XSLT 2.0. Первая схема (s1.xsd) импортирует вторую схему (s2.xsd) следующим образом:Объединить две схемы xml с использованием XSLT

Содержание s1.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema.xsd" 
    xmlns:ns1="URI1" targetNamespace="URI2" 
    elementFormDefault="qualified" attributeFormDefault="unqualified"> 
    <import namespace="URI1" schemaLocation="s2.xsd"/> 
    <element name="element1"/> 
    <element name="element2"/> 
</schema> 

и содержание s2.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:ns1="URI1" targetNamespace="URI1"> 
    <attribute name="attr1"/> 
<schema> 

Мои XSLT объявляет пространство имен XS следующим образом:

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

Я хотел бы объединить узлы s2.xsd в < схема > -элемент s1.xsd. До сих пор я пробовал

<xsl:template name="merge_imported_schemas"> 
    <xsl:for-each select="/schema/import[@namespace = //namespace::*]"> 
     <!-- file exists? --> 
     <xsl:choose> 
      <xsl:when test="boolean(document(@schemaLocation))"> 
       <!-- schema found --> 
       <xsl:copy-of select="document(@schemaLocation)/*/node()"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <!-- schema not found --> 
       <xsl:message terminate="yes"> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each> 
</xsl:template> 

но я не получил желаемого результата. Может ли кто-нибудь рассказать мне, что я делаю неправильно? Я подозреваю, что здесь есть пространство имен, но, честно говоря, я немного ошибаюсь в использовании пространств имен. Благодаря!

+0

Что я действительно хотел, было добавить содержимое s2.xsd в s1.xsd, а затем разобрать s1.xsd в виде одного файла. Насколько мне известно, это невозможно, но в процессе работы используется временное дерево результатов (см., Например, http://www.xml.com/pub/a/2003/12/03/tr.html) , Для этого вызов , похоже, делает трюк. – conciliator

ответ

2

Вам необходимо квалифицировать элементы в XPath. На данный момент select="/schema/import[@namespace = //namespace::*]"> ничего не соответствует, потому что нет элемента /schema. XPath пытается сопоставить элементы с пространством имен no.

Измените его на select="/xs:schema/xs:import[@namespace = //namespace::*]">, и он должен работать.

Помните, что префиксы пространства имен являются псевдонимом для URI пространства имен, и если у вас есть пространство имен по умолчанию (как в ваших xsd-файлах), элементы без префикса все еще имеют пространство имен.

В качестве альтернативы вместо <xsl:for-each select="/schema/import[@namespace = //namespace::*]"> у вас может быть больше успеха с использованием <xsl:apply-templates select="/xs:schema/node()" и определения различных шаблонов для разных типов узлов, которые вы хотите скопировать в дерево вывода.

+0

Спасибо, Пол, я забыл. :) Добавив мой запрос XPath с правильными префиксами пространства имен, я решил попробовать подсчитать количество узлов. Как это: До: После: К сожалению, они оба дают мне то же число (44, что, на наш взгляд, всего лишь на 2 больше, чем ответ на все). – conciliator

+0

Из приведенной информации, похоже, что вы можете отбрасывать элементы из исходной схемы. –

+0

Ну, это может быть так. Однако я изменил на (подсчитывая количество элементов, находящихся прямо под/схемой в s2. XSD). Это говорит 22 ... Я добрый, потерянный. – conciliator

Смежные вопросы