2010-09-20 2 views
1

Я думаю, что лучший способ задать этот вопрос: Как указать пространство имен по умолчанию для корневого элемента в выходе? Делать это:Oracle XSLT: пространство имен по умолчанию приводит к пустым тегам

<xsl:template match="/"> 
     <r xmlns:s"http://www.mycompany.com/s/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/default/schema" > 
.... 
.... 

дает мне ошибку в Oracle:

 
ORA-31011: XML Parsing Failed 
ORA-19201: Error occurred in in XML Processing 
LPX-00604: Invalid attribute 'nIfNotExist', for attribute 'name' 
ORA-06512: at SYS.XMLType at line 74 
ORA-06512: at line 24 

где 'nIfNotExist' шаблон:

<xsl:template name="nIfNotExist" xmlns:scom="http://www.mycomapny.com/s/schema"> 
    <xsl:param name="nodeToTest"/> 
    <xsl:param name="nodeName"/> 
       ... 

Я хочу, чтобы результирующий документ, чтобы корневой элемент выглядеть это:

<r xmlns:s="http://www.mycompany.com/s/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/default/schema"> 

Я хочу "http://www.mycompany.com/default/schema" как пространство имен по умолчанию, чтобы документ мог пройти проверку XSD. В противном случае я должен добавить его вручную, прежде чем запускать проверку (не вариант пакетной обработки).

EDIT

Я попытался это:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:s="http://www.mycompany.com/schema" 
xmlns="http://www.mycompany.com/def_schema"> 

В результате документ без каких-либо данных, как это:

<r xmlns:s="http://www.mycompany.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/def_schema"> 
    <a></a> 
    <s:b></s:b> 
    <c></c> 
    .... 

Это должно было быть:

<r xmlns:s="http://www.mycompany.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/def_schema"> 
    <a>123</a> 
    <s:b>ABC34L</s:b> 
    <c>7.092381</c> 

UPDATE

Источник данных выглядит примерно так (вход, который я получаю не имеет пространства имен, определенных в нем):

<ROOT_NODE> 
    <DATA_A>1234</DATA_A> 
    <DATA_B>34567</DATA_B> 
    <OTHER_DATA_C>7.123456</OTHER_DATA_C> 
</ROOT_NODE> 

Желаемая выход

<r xmlns:s="http://www.mycompany.com/schema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://www.mycompany.com/def_schema"> 
    <a>1234</a> 
    <s:b>34567</s:b> 
    <c>7.123456</c> 
</r> 
+0

Пожалуйста, предоставьте исходный XML-документ, на котором применяется преобразование. Кроме того, пожалуйста, укажите результат, который вы хотите получить от преобразования. –

+0

@Dimitre Novatchev: Совершено. – FrustratedWithFormsDesigner

+0

Я отправил свой ответ и содержит достаточно короткое и прямолинейное, полное решение. –

ответ

0

Существует множество возможных решений, но ни один из них не работает в Oracle, от PL/SQL. Один из других разработчиков здесь «решил» это путем преобразования объекта XML в CLOB, выполняя некоторые манипуляции с строкой, чтобы принудительно использовать пространство имен по умолчанию в корневой элемент, а затем преобразовать обратно в XML для следующего шага ... Я не но он работает ...

0

Вы находитесь на полпути к правильный ответ. Когда вы объявляете пространство имен по умолчанию в корне преобразования, вы утверждаете (предполагая, что вы не переопределяете объявление в другом месте), что все неквалифицированные элементы в этом документе принадлежат этому пространству имен. Каждый неквалифицированный элемент, который излучает преобразование, будет принадлежать этому пространству имен. У вас есть эта часть права.

Я думаю, что вы, вероятно, не замечаете, что объявления пространств имен в преобразовании XSLT также применяются к шаблонам XPath в преобразовании. Я бы сказал, что тесты узла XPath в вашем преобразовании не соответствуют ни одному из входных узлов, поскольку входные узлы находятся в пустом пространстве имен, а не в пространстве имен, которое вы указали в преобразовании.

То, что вы, вероятно, хотите сделать что-то вроде этого:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:s="http://www.mycompany.com/schema" 
xnlns:no="" 
xmlns="http://www.mycompany.com/def_schema"> 

... а затем изменить шаблоны в преобразовании соответственно:

<xsl:template match="no:foo"> 
    <foo>...</foo> 
</xsl:template> 

Это, кстати, один причин, по которым существует xsl:element - вы можете создать шаблон, который преобразует элементы из одного пространства имён в другое с ним, например:

<xsl:template match="no:*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:element> 

Edit:

Я не играл с пространством имен совсем таким образом, прежде, и оказывается, что выше на самом деле не законно. Вы не можете указать пространство имен с префиксом пространства имен. Таким образом, вы не можете использовать целевое пространство имен как пространство имен по умолчанию вашего преобразования, потому что тогда вы не можете сказать XPath, чтобы найти элементы в исходном документе.

Вы можете указать выходное пространство имен с префиксом, например:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:s="http://www.mycompany.com/schema" 
xmlns:out="http://www.mycompany.com/def_schema"> 

... но что будет писать префикс out пространства имен на выход, который не будет беспокоить любой XML-процессор, но может беспокоить людей. Или вы можете указать его в явном виде в шаблонах, например:

<xsl:template match="foo"> 
    <xsl:element name="foo" namespace="http://www.mycompany.com/def_schema"> 
     ... 
    </xsl:element> 
</xsl:template> 
+0

Трюк с 'xmlns: no =" "' заставляет Oracle сказать «LPX-00284: префикс пространства имен в NULL URI не разрешен». Кроме того, PL/SQL Developer не позволяет этого, заявив, что только пространство имен по умолчанию может быть нулевым (я обманул - мне пришлось загрузить его из текстового редактора, а не из XML-редактора). – FrustratedWithFormsDesigner

+0

Ваше второе предложение, возможно, сработает ... Я получил пространство имен по умолчанию, появившееся в корневом узле на выходе! Единственная проблема ... Мне все еще нужны объявления других пространств имен (пространство имен '' '' 'и пространство имен' xsi'). Похоже, что Oracle не поддерживает элемент 'xsl: namespace' ... Предполагая, что Oracle только (безопасно) поддерживает XSLT 1.0, как я могу указать несколько пространств имен, объявленных на элементе? – FrustratedWithFormsDesigner

+0

Если ваше преобразование испускает любые узлы в этих двух пространствах имен, XSLT будет добавлять объявления пространства имен. Если нет, это не так. Но вам не нужны эти объявления пространств имен, если в этих пространствах имен нет узлов. –

1

Это преобразование:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:s="http://www.mycompany.com/schema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://www.mycompany.com/def_schema" 
> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/*"> 
    <r> 
    <xsl:apply-templates/> 
    </r> 
</xsl:template> 

<xsl:template match="DATA_A"> 
    <a> 
    <xsl:apply-templates/> 
    </a> 
</xsl:template> 

    <xsl:template match="OTHER_DATA_C"> 
    <c> 
    <xsl:apply-templates/> 
    </c> 
    </xsl:template> 

    <xsl:template match="DATA_B"> 
    <s:b> 
    <xsl:apply-templates/> 
    </s:b> 
    </xsl:template> 
</xsl:stylesheet> 

при нанесении на поставленном XML документа:

<ROOT_NODE> 
    <DATA_A>1234</DATA_A> 
    <DATA_B>34567</DATA_B> 
    <OTHER_DATA_C>7.123456</OTHER_DATA_C> 
</ROOT_NODE> 

производит желаемый результат:

<r xmlns:s="http://www.mycompany.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.mycompany.com/def_schema"> 
    <a>1234</a> 
    <s:b>34567</s:b> 
    <c>7.123456</c> 
</r> 
+0

Хмм, я пробовал это в Oracle (точный вход и XSLT, как здесь), и все, что он произвел, было ' 1234345677.123456' (Oracle 10g) По крайней мере, это получил пространство имен по умолчанию. Тот же метод не работал над основным документом, хотя в основном документе есть только один шаблон для корневого элемента, а затем все остальные преобразования под ним. – FrustratedWithFormsDesigner

+0

Кажется, что это конкатенация содержимого 'DATA_A',' DATA_B' и 'OTHER_DATA_C' и создание содержимого' r'. – FrustratedWithFormsDesigner

+0

@FrustratedWithFormsDesigner: Тогда либо у вас нет того же XML, что и тот, который вы предоставили, или процессор XSLT ORacle, который вы используете, имеет некоторую ошибку. –

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