XSLT: цикл for-each с ключом, не возвращающим все узлы

Я начинающий XSLT-разработчик. Меня попросили исправить проблему в проекте, в котором исходного разработчика больше нет с нами. В XSLT есть цикл for-each, использующий key и count.

<xsl:for-each select="ns0:BOM[count(. | key('subsat', ns0:BomText01)[1]) = 1][ns0:BomText01]"> 
   ... 

Это key:

<xsl:key name="subsat" match="ns0:Parts/ns0:BOM[ns0:FindNum!='0']" use="ns0:BomText01" />

В трансформируемом XML-файле есть два одноуровневых узла, которые представляют подчасти:

<ns0:BOM referentId="10000:65091335:65359080">
  <ns0:BomText01>3069260-303-SUB0027</ns0:BomText01> 
  <ns0:ItemNumber>My_part_1</ns0:ItemNumber> 
  <ns0:ItemType>Part</ns0:ItemType> 
  <ns0:Qty>67</ns0:Qty> 
</ns0:BOM>
<ns0:BOM referentId="10000:65102551:86713230">
  <ns0:BomText01>3069260-303-SUB0027</ns0:BomText01> 
  <ns0:ItemNumber>My_part_2</ns0:ItemNumber> 
  <ns0:ItemType>Part</ns0:ItemType> 
  <ns0:Qty>67</ns0:Qty> 
</ns0:BOM>

Однако цикл выбирает только первый узел (My_part_1). Я подозреваю, что это из-за count=1, но я действительно не знаю. И я не знаю, как его изменить. Идеи? Если мне нужно включить больше данных, дайте мне знать.


person MikeTWebb    schedule 17.06.2014    source источник
comment
Пожалуйста, включите полный контекст вашего источника XML (родительские элементы, объявления пространств имен и т. д.) и все соответствующие шаблоны вашего документа XSLT (включая корневой узел, ключевые объявления, полный шаблон для каждого выше и внутри него и любые другие шаблоны, которые называются)   -  person helderdarocha    schedule 17.06.2014
comment
@Helderdarocha ... Я бы хотел, но это проприетарный контент. У меня могут уйти часы, чтобы разделить его и сделать универсальным. Есть ли у вас какие-либо предложения о том, как работает счет в foreach?   -  person MikeTWebb    schedule 17.06.2014
comment
Ok. Я посмотрю. Также ваш key кажется недействительным. Это должно быть допустимое полное имя — оно не должно начинаться с цифры. Вы вообще умеете его запускать? Какой процессор вы используете?   -  person helderdarocha    schedule 17.06.2014
comment
Спасибо! Я возьму ключевую часть XSLT. Я просто поместил туда этот текст, потому что думаю, что он используется.   -  person MikeTWebb    schedule 17.06.2014
comment
Я разместил ответ. Возможно, вы можете применить это к вашему реальному примеру. Выражение count с ключом фактически используется для выбора уникальных значений, поэтому в вашем примере будет выбрано только первое, поскольку оба имеют одинаковые BomText01.   -  person helderdarocha    schedule 17.06.2014


Ответы (1)


Предположим, что соответствующая часть вашего XSLT выглядит примерно так:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ns0="ns0" version="1.0">

    <xsl:key name="subsat" match="ns0:BOM[ns0:FindNum!='0']" use="ns0:BomText01"/>

    <xsl:template match="ns0:Parts">
        <xsl:for-each 
            select="ns0:BOM[count(. | key('subsat', ns0:BomText01)[1]) = 1][ns0:BomText01]">
            <xsl:value-of select="."/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Он напечатает только первый из элементов, потому что он выбирает BOM элементов, которые имеют уникальное значение BomText01. Это ожидаемый результат.

Если BomText01 является полем идентификатора (как кажется) и вы ожидали получить оба результата (возможно, потому что их ItemNumber содержит разные значения), ошибка, возможно, в вашем источнике (который присвоил одинаковые идентификаторы, когда это не должно было делать так).

Если вы измените одно из этих значений в источнике, вы сможете выбрать оба и проверить это.

person helderdarocha    schedule 17.06.2014
comment
@Held... Я смотрю на источник. Спасибо - person MikeTWebb; 17.06.2014
comment
@Held... Я нашел ответ. Я изменил =1, чтобы он был ›= 1 в for-each. Это собрало все одноуровневые узлы с BomText01, имеющим то же значение ключа, что и «subsat». - person MikeTWebb; 18.06.2014
comment
@Помогите... Я собираюсь проголосовать за ваш ответ, потому что он был для меня поучительным. Я не знаю, правильно ли это принять, поскольку ответом было ›=1. Спасибо за отзыв, однако - person MikeTWebb; 18.06.2014