2015-11-17 3 views
0

У меня есть массив XML <row> элементов, каждый из которых может иметь массив из <query> элементов. Это выглядит примерно так:XSLT: Как проверить равенство детей

<row><query></query><query></query></row> 
<row><query></query><query></query></row> 
<row><query></query><query></query></row> 
<row><query></query><query></query></row> 

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

Я составление <xsl:when> для этого:

<xsl:choose> 
    <xsl:when test="[Table condition]"> 
    <!--code to print table--> 
    </xsl:when> 
    <xsl:otherwise> 
    <!--code to print string--> 
    </xsl:otherwise> 
</xsl:choose> 

Каким должен быть Table Condition?

Я использую XSLT v 1.0. Я знаю, что есть что-то под названием deep equals, но не понимаю, как его использовать здесь.

Вы можете мне помочь?

+0

Извините, не понимаю, что вам нужно ... Просьба предоставить образцы данных (в пределах вашей пустой структуры XML) и ожидаемого результата. – Shnugo

+0

Вы просто хотите сравнить количество дочерних элементов? Или их данные? –

+0

@MartinHonnen Я хочу сравнить их данные. Предполагается, что число детей всегда равно во всех 'row', но данные могут отличаться. –

ответ

0

deep-equal является функция, введенная в XSLT/XPath 2.0, здесь приведен пример, используя, что (который затем естественно требует использования процессора XSLT 2.0, как Saxon 9, Altova, XmlPrime):

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="table[not(row[some $sibling in ../row satisfies not(deep-equal(., $sibling))])]"> 
     <xsl:value-of select="row/query" separator=","/> 
    </xsl:template> 
</xsl:transform> 

У меня очевидно, поставили условие для одного случая в шаблон match и просто разрешили копирование других таблиц через преобразование идентичности.

С входом образца как

<root> 
    <table> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
    </table> 
    <table> 
     <row><query>2</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
    </table> 
</root> 

результат

<root> 
    1,2,1,2,1,2,1,2 
    <table> 
     <row><query>2</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
     <row><query>1</query><query>2</query></row> 
    </table> 
</root> 
+0

Есть ли способ сделать это в XSLT 1.0? Я использую это. –

+0

Знаете ли вы количество элементов 'query' при написании кода XSLT? –

+0

Нет, не знаю.Они могут различаться, но число их одинаково для всех элементов 'row'. –

0

Если есть только текст внутри ваших query элементов, оно не должно быть слишком сложным в XSLT 1.0. Например, я предполагаю, что образец из двух rows может выглядеть следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <row><query>foo</query><query>foo</query></row> 
    <row><query>foo1</query><query>foo2</query></row> 
</root> 

Если обрабатывать эти данные с помощью шаблона XSLT как

<xsl:for-each select="//row"> 
     <xsl:choose> 
      <xsl:when test="query[not(. = preceding-sibling::query or . = following-sibling::query)]"> 
       There is at least one query element which is different from the others 
       in the same raw. 
      </xsl:when> 
      <xsl:otherwise> 
       All query elements in this row are equal. 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each> 

вы получите ожидаемый результат: Первый row лечится как «равный», другой - «другой». Это делается путем проверки того, соответствуют ли предыдущие и следующие query: Есть ли хотя бы один, который не равен всем предыдущим и последующим братьям и сестрам?

Это более или менее то, что вы ищете?

+0

Это опасное сравнение, нет? Если у вас есть ' аб с и' Ьс ', то ваше сравнение дает истинное, хотя значения различны. –

+0

Не обязательно текст внутри 'query'. У него может быть один или несколько детей. Мы можем предположить, что дети в строке '' '' для одной и той же позиции 'запроса' имеют те же теги, но могут не иметь одинакового значения, и именно это я пытаюсь сравнить. –

+0

@ Мартин Хоннен, по крайней мере, с Saxon 6, он возвращает «ложь» в обоих случаях (как и должно быть) @Core_Dumped: Ну, в этом случае мое предложенное решение не будет работать. Обходным путем может быть преобразование всего содержимого 'query' в строку и последующее сравнение. – cis

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