2008-11-25 5 views
1

У меня есть определение XML, содержащее элемент с дочерними элементами. Например:Создание SQL с использованием XML и XSLT

<a> 
<b> 
    <c>C</c> 
    <d>D</d> 
</b> 
</a> 

У меня есть XSLT с выходом текста. Например:

<xsl...> 
    <xsl:output method="text" indent="yes"/> 
    <xsl:template match="/"> 
    <xsl:copy-of select="https://stackoverflow.com/a/b" /> 
    ... 

Я хочу, чтобы скопировать весь элемент Ь и его потомок в строку пробельной-удалено, так что я могу генерировать запрос SQL. Например:

select * from some-table where xml = '<b><c>C</c><d>D</d></b>' 

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

Любые идеи?

ответ

-1

Вот как это можно сделать:

<xsl:output method="xml" /> 

<xsl:template match="/"><xsl:apply-templates select="https://stackoverflow.com/a/b" mode="normalize-space" /></xsl:template> 

<xsl:template match="text()" mode="normalize-space"><xsl:value-of select="normalize-space(.)" /></xsl:template> 
<xsl:template match="@*|node()" mode="normalize-space"><xsl:copy><xsl:apply-templates select="@*|node()" mode="normalize-space" /></xsl:copy></xsl:template> 

Этот метод копирует узлы, узлы с пространствами имен и атрибутов.

Метод требует, чтобы результат был «xml» (не «текст», как в исходном образце). Он использует собственный шаблон для всех узлов TEXT, чтобы нормализовать пространство внутри них (удалить ведущие/конечные пробелы, сконденсировать несколько пробелов в одно пространство). Затем он использует простой шаблон «identity», который копирует все узлы и их атрибуты. Оба шаблона используют специальный режим, чтобы не мешать остальной части XSL.

К счастью, XSLT-процессор копирует все «неизвестные» узлы внутри тега xsl: template в выходной документ, а пробелы являются одним из таких узлов. Вот почему все эти шаблоны необходимо писать в одной строке без лишних пробелов.

PS Хотя, я согласен с тем, что поиск нормализованного XML в РСУБД довольно странный.

1

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

Я считаю, что как Oracle (определенный), так и SQL Server (думаю, так) имеют механизмы для выполнения запроса к столбцу, содержащему XML, более удобным для XML способом (например, с использованием XPath).

Что именно вы пытаетесь сделать? Ваша проблема кажется глубже, чем просто заставить XSLT правильно преобразовываться.

+0

Точка вопроса - это не содержимое xml или запроса, а собственно копирование XML в обычный текст. – 2008-11-25 22:55:58

+0

SQL Server 2000 (целевая база данных) поддерживает XML-генерацию, но вызывает парсер MSXML. За кулисами это приводит к поеданию в память, используемому SQL Server (примерно треть я сказал). Это нежелательно, так как это закончится в критичной для производительности системе. – 2008-11-25 22:59:49

1

Возможно, это слишком сложная задача для XSLT. Ближайший я могу получить это:

<xsl:template match="b//*|node()"> 
    <xsl:copy> 
     <xsl:text>&lt;</xsl:text> 
     <xsl:value-of select="name()"/> 
     <xsl:text>&gt;</xsl:text> 
     <xsl:value-of select="text()"/> 
     <xsl:apply-templates select="*"/> 
     <xsl:text>&lt;/</xsl:text> 
     <xsl:value-of select="name()"/> 
     <xsl:text>&gt;</xsl:text> 
    </xsl:copy> 
    </xsl:template> 

И вызывается:

<xsl:apply-templates select="https://stackoverflow.com/a/b/self::*"/> 

Это производит следующее:

<b> 
    <c>C</c> 
    <d>D</d> 
</b> 

Где мое «решение» падает, когда элементы имеют атрибуты. Если b имеет атрибут, значение атрибута выписывается. Я не могу найти способ записи атрибутов, когда и когда они встречаются ...

Любые идеи?

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