#xml #xslt
#xml #xslt
Вопрос:
Я работаю с большими и сложными словарными данными (XML), которые необходимо анализировать с помощью XSL и выводить XML.
что будет рассматриваться как «лучший» способ проверить, обрабатывает ли XSL все узлы из XML (ввода)?
пожалуйста, рассмотрите этот простой пример, я думаю, он будет отражать суть проблемы:
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<a>
<b>
<c>
some1
<d>text2</d>
more text1
</c>
</b>
<b>
<c>
some2
<d>text2</d>
more text2
</c>
</b>
<d>text3</d>
<e>
text
<d>4</d>
</e>
</a>
некоторые tarnsformations.xsl
output.xml
<?xml version="1.0" encoding="UTF-8"?>
<amodified>
<bmodified>
some1
<dd>text2</dd>
more text1
</bmodified>
<bmodified>
some2
<dd>text2</dd>
more text2
</bmodified>
<dd>text3</dd>
<ed>text</ed>
<dd>4</dd>
</amodified>
В output.xml названия тегов были изменены, а также порядок содержимого (по сравнению с входным файлом).
Мне нужно сравнить, доступны ли все текстовые поля из ввода на выходе.
Я думаю, что лучшим решением было бы создать тест, который будет извлекать текст из каждого тега и сравнивать его строка за строкой, выводя теги, которые не существуют в output.xml в файл журнала … ?
Комментарии:
1. Вопрос без единого примера не является конструктивным. Что такое «лучший» и что такое «обработка всех узлов»? Я предполагаю, что простая обработка всех узлов — это не то, что должны проверять тесты. Как насчет «генерации правильных результатов»? Этот вопрос, как и было задано, имеет очень мало общего с XSLT и с тестированием. Пожалуйста, отредактируйте и улучшите.
Ответ №1:
Я бы рекомендовал два вида тестов: сначала модульный тест на меньшем контролируемом наборе данных, который должен быть моделью для данных, которые вы найдете в своем большом словаре. Это можно рассматривать как модульный тест для вашего процесса xslt. Обычно я извлекал несколько репрезентативных фрагментов из большего набора данных и сохранял их вместе с тестовым кодом. Затем тест применяет преобразование к тестовым данным и делает утверждения о результате, проверяя, что преобразование было успешно использовано.
Затем дополнительно вы должны встроить проверки работоспособности в свою производственную систему, чтобы (например) убедиться, что общее количество обработанных узлов соответствует ожидаемому. Например, в словаре с большим количеством записей вы можете выполнить один шаг для подсчета всех записей, а затем еще один для их обработки. Затем в конце посмотрите, сколько записей вы обработали, и убедитесь, что количество совпадает с тем, что вы ожидали. Это также полезно, поскольку предоставляет средство вывода индикатора выполнения (% завершения).
В любом случае, это то, что мы делаем.
Если текст на выходе совпадает с текстом на входе, как в вашем примере, Марчин, вы можете довольно легко сравнить их с помощью xslt. Если вы обрабатываете XML-файл с пустой таблицей стилей xslt (только <xslt:stylesheet />
узел), вы получите обратно только текст без разметки. Я думаю, что xmllint тоже может это сделать. Так что просто запустите это как для ввода, так и для вывода и сравните, используя простое сравнение текста (например, diff).
Комментарии:
1. @_Mike: Как правило, нет сопоставления 1: 1 между обрабатываемыми узлами и выводом узлов. Общее решение состоит в том, чтобы предоставлять отладочный вывод всякий раз, когда обрабатывается узел, чтобы можно было подсчитать «обработанные показатели» в конечном выводе.
2. @Dmitri — это правда; но во многих случаях вы могли бы посчитать количество ожидаемых выходных узлов и сравнить.
3. @_Mike: Да, но вопрос не в том, как проверить количество выходных узлов. Вопрос в том, как проверить, что каждый входной узел был обработан .
4. @Dmitri Да, я понимаю. Подход в вашем ответе заключается в создании некоторого специального вывода, который гарантированно создает один выходной узел на входной узел. Я предлагаю убедиться, что фактический результат соответствует ожиданиям, используя какое-то независимо вычисляемое свойство ожидаемого результата, например, подсчет количества выходных узлов — очень часто это может быть функцией правильной обработки всех входных данных. По общему признанию, это не всегда так, но особенно в словаре, состоящем в основном из списка записей, это, вероятно, будет хорошим подходом?
5. @_Mike: Чтобы ответить на ваш вопрос: даже если входные данные представляют собой словарь, если задача не требует создания соответствующего вывода для некоторых записей, в зависимости от определенных условий, то, просто проверяя выходные данные, мы не можем выяснить, был ли обработан каждый узел словаря или нет.
Ответ №2:
Можно использовать этот метод:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:variable name="vrtfResults">
<xsl:apply-templates select="num"/>
</xsl:variable>
<xsl:variable name="vProcessed" select=
"count(ext:node-set($vrtfResults)/nodeProcessed)"/>
<xsl:variable name="vAll" select="count(num)"/>
<xsl:text>From the existing </xsl:text>
<xsl:value-of select="$vAll"/>
<xsl:text> amp;<num> elements </xsl:text>
<xsl:value-of select="$vProcessed"/>
<xsl:text> were processed.</xsl:text>
</xsl:template>
<xsl:template match="num">
<nodeProcessed/>
<num><xsl:value-of select="2*."/></num>
</xsl:template>
</xsl:stylesheet>
при применении к следующему XML-документу:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
получен желаемый результат:
From the existing 10 <num> elements 10 were processed.
Объяснение:
-
Для обработки каждого элемента был добавлен специальный элемент только для тестирования (
<nodeProcessed/>
)<num>
. -
Мы фиксируем выходные данные в переменной, затем подсчитываем количество
<nodeProcessed/>
элементов и сравниваем их с общим количеством<num>
элементов, которые должны быть обработаны.