2016-10-18 3 views
0

Учитывая эту структуру:XSLT2 - тест, который узел приходит первым среди вариантов

<body> 
    <h1>Main Title</h1> 
    <p class="sectiontitle>Title</p> 
    <p class="bodytext">some text</bodytext> 
    <ul>...</ul> 
    <p class="paragraphtitle>Subtitle</p> 
    <p class="bodytext">some text</bodytext> 
</body> 

или это один, где paragraphtitle и sectiontitle перепутаны:

<h1>Main Title</h1> 
    <p class="paragraphtitle>Title</p> 
    <p class="bodytext">some text</bodytext> 
    <ul>...</ul> 
    <p class="sectiontitle>Subtitle</p> 
    <p class="bodytext">some text</bodytext> 
</body> 

Я преобразуя этот XML-структуры в другую аромат XML (DITA), и для этого мне нужно знать, какой узел на первом месте, потому что это говорит мне, как обрабатывать остальную часть файла.
Нет другого способа обработать файл, пока я не узнаю, что было первым.
Я знаю, что перед любым из этих заголовков будет элемент h1, h2, h3 .... Там может быть <p class=bodytext> элементов в любом месте между основным заголовком и тегом закрывающего тела. Это очень случайно.

Как я могу узнать, что на первом месте: sectiontitle p или paragraphtitle p.

Я попытался с некоторыми сумасшедшими выражения ставят в выбор, как:

body/p[@class='sectiontitle'][1]/preceding-sibling::p[@class!='paragraphtitle'][last()]/preceding-sibling::*[not(self::p[@class='sectiontitle' or @class='paragraphtitle']) and preceding-sibling::h1] 

или

body/p[@class='paragraphtitle'][1]/preceding-sibling::p[@class!='sectiontitle'][last()]/preceding-sibling::*[not(self::p[@class='sectiontitle' or @class='paragraphtitle']) and preceding-sibling::h1] 

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

Есть ли способ получить абсолютную позицию? Что-то вроде

if absposition(paragraphtitle[1]) < absposition(sectiontitle[1]) then 
+0

Почему вы должны знать, что первично? Какую ** настоящую ** проблему вы пытаетесь решить здесь? –

+0

Я пытаюсь определить файл, чтобы знать, как его обрабатывать, я знаю 2 формы: sectiontitle first, of paragraphtitle first, основываясь на этом, я использую другой путь для каждого. – Flag

ответ

0

Есть ли способ получить абсолютную позицию?Нечто подобное, если absposition(paragraphtitle[1]) < absposition(sectiontitle[1]) then

Я считаю, что ваше состояние может быть пересчитаны как:

Если есть paragraphtitle перед первым sectiontitle, затем ...

, который может быть выражен как:

<xsl:choose> 
    <xsl:when test="/body/p[@class='sectiontitle'][1]/preceding-sibling::p[@class='paragraphtitle']">paragraph title is first</xsl:when> 
    <xsl:otherwise>section title is first</xsl:otherwise> 
</xsl:choose> 

Это будет работать как для XSLT 1.0, так и для 2.0. Как уже упоминалось, в XSLT 2.0 вы можете моделировать испытания, чтобы соответствовать в точности исходное заявление:

<xsl:when test="/body/p[@class='paragraphtitle'][1] &lt;&lt; /body/p[@class='sectiontitle'][1]">paragraph title is first</xsl:when> 

или:

<xsl:when test="/body/p[@class='sectiontitle'][1] >> /body/p[@class='paragraphtitle'][1]">paragraph title is first</xsl:when> 
+0

Это намного проще, чем я ожидал, и это делает трюк. Спасибо! – Flag

0

В XSLT 2.0 вы можете использовать << оператор:

if (p[@class='paragraphtitle'] << p[@class='sectiontitle']) ... 

В 1.0 Вы не имеете реальный вариант, кроме предыдущего-собрата и ниже-собрата. Но я не могу дать рекомендации по деталям, потому что ваши выражения-кандидаты включают детали, которые не нужны для того, чтобы отличить эти два образца (например, тестирование для элемента h1, который присутствует в обоих), и я предполагаю, что вы добавили эти дополнительные условия в там по какой-то причине.

Другой вариант (требуется расширение узла) состоит в том, чтобы отфильтровать список, исключив все незаинтересованные элементы, а затем протестировать отфильтрованный список, используя <xsl:if test="p[1][self::sectiontitle]">.

Или, возможно, стоит спросить, почему вы это делаете, какова реальная основная проблема? Возможно, ваша настоящая цель - переупорядочить элементы в какой-то канонический порядок, и в этом случае мы должны смотреть на методы сортировки.

+0

Благодарим вас за ответ Майкл. Я добавил немного информации, но я сталкиваюсь с файлами, которые сильно различаются. Я только что обнаружил функцию node-before, пытаясь найти информацию об упомянутом вами операторе <<. Я собираюсь уйти. – Flag

+0

Обратите внимание, что вы не можете использовать оператор '<<', не избегая его как '< <'. –

+0

@Flag функция op: node-before как раз здесь, как способ задания семантики оператора '<<'. Эта функция недоступна как таковая для пользовательских приложений. –

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