2012-05-01 3 views
0

У меня есть образецКоличество XSLT-двойников

<Root> 
    <A rename="yes,it is option 1"/> 
    <C rename="no"/> 
    <A rename="yes,it is option 2"/> 
    <C rename="no"/> 
    <C rename="yes"/> 
    <C rename="no"/> 
    <A rename="yes,it is option 3"/> 
    <A rename="yes,it is option 4"/> 
    <C rename="no"/> 
    <C rename="yes"/> 
    <C rename="no"/>  
    <C rename="no"/>   
</Root> 

тогда я применить шаблон выглядеть следующим образом

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:template match="A"> 
      <p><b>option1: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 1')]])"/></b></p> 
      <p><b>option2: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 2')]])"/></b></p>    
      <p><b>option3: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 3')]])"/></b></p> 
      <p><b>option4: <xsl:value-of select="count(following-sibling::C[preceding-sibling::A[1]/@rename[contains(.,'option 4')]])"/></b></p>       
</xsl:template> 
</xsl:stylesheet> 

, но я хочу, чтобы выходной выглядеть следующим образом, если не родственный следующие A, мы просто игнорировать этот one.just печатать эти @rename содержит «вариант», а также содержит элементы

option1: 1 

option2: 3 

option4: 4 

, что я получаю сейчас

option1: 1 

option2: 3 

option3: 0 

option4: 4 

option1: 0 

option2: 3 

option3: 0 

option4: 4 

option1: 0 

option2: 0 

option3: 0 

option4: 4 

option1: 0 

option2: 0 

option3: 0 

option4: 4 
+1

Теперь это довольно хороший пример того, как не использовать XML. Зачем использовать структурированный формат, когда вы не даете своим данным какую-либо структуру? – Tomalak

+0

Также * вы на самом деле не попробовали * свой отображаемый XSLT-код с вашим вводом. Я получаю в значительной степени результат, который вы хотите. Пожалуйста, приложите больше усилий в свой вопрос, невозможно помочь вам, если ваш код и ваш текст вопроса расскажут две разные истории. – Tomalak

+0

Я просто хочу упростить свой исходный файл –

ответ

1

Вы подсчет всех С элементы, которые следуют самым последним элементом. Это может быть сделано с помощью ключа, чтобы сгруппировать все такие Ĉ элементов с соответствующей A элемента

<xsl:key name="lookup" match="C" use="generate-id(preceding-sibling::A[1])" /> 

Для того, чтобы найти A элементов, для которых по меньшей мере один следующего С существует, вы затем сделать это:

<xsl:apply-templates select="A[key('lookup', generate-id())]" /> 

, а затем подсчитать количество вариантов, вы можете просто подсчитать количество элементов в ключе, например, так:

<xsl:value-of select="count(key('lookup', generate-id()))" /> 

Попробуйте следующий XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" indent="yes"/> 
    <xsl:key name="lookup" match="C" use="generate-id(preceding-sibling::A[1])" /> 

    <xsl:template match="/Root"> 
     <xsl:apply-templates select="A[key('lookup', generate-id())]" /> 
    </xsl:template> 

    <xsl:template match="A"> 
     <xsl:value-of select="concat(@rename, ': ', count(key('lookup', generate-id())) , '&#13;&#13;')" /> 
    </xsl:template> 
</xsl:stylesheet> 

Когда это применяется к вам образец XML, следующий выход:

yes,it is option 1: 1 

yes,it is option 2: 3 

yes,it is option 4: 4 

Обратите внимание, что если вы хотите 'option1' вместо ' да, это вариант 1 ', вы можете сделать concat('option', substring-after(@rename, 'option ')) вместо @rename

Примечание: этот вопрос может быть упрощен d, если вы переструктурировали свой XML. Нечто подобное было бы намного лучше:

<Root> 
    <A rename="yes,it is option 1"> 
     <C rename="no"/> 
    </A> 
    <A rename="yes,it is option 2"> 
     <C rename="no"/> 
     <C rename="yes"/> 
     <C rename="no"/> 
    </A> 
    <A rename="yes,it is option 3"/> 
    <A rename="yes,it is option 4"> 
     <C rename="no"/> 
     <C rename="yes"/> 
     <C rename="no"/> 
     <C rename="no"/> 
    </A> 
</Root> 
+0

, но элементы A и C не являются родительскими и дочерними, они просто братья и сестры, –

+0

Да, я знаю! Я просто сказал, что было бы легко закодировать XSLT, если бы они были родителями и дочерними. –

+0

да, я больше смущен о том, чтобы иметь дело с этими отношениями родного брата. –

0

В XSLT 2.0 это превращается в простой вопрос группировки, используя xsl:for-each-group инструкцию.

<xsl:template match="Root"> 
    <xsl:for-each-group group-starting-with="A" select="*"> 
    <xsl:if test="count(current-group()) != 1"> 
     <p>Option <xsl:value-of select="substring-after(current-group()[1]/@rename, 'option ')"/> = <xsl:value-of select="count(current-group())-1"/></p>  </xsl:if> 
    </xsl:for-each-group> 
</xsl:template> 
+0

Кажется интересным, где я могу найти больше таких примеров? –

+0

Я узнал все, что я знаю о XSLT 2.0, из книги, отличной XSLT 2.0 Programmers Reference от Wrox. – samjudson

+0

ой спасибо очень много, это один XSLT 2.0 Справочник программиста, третье издание Майкл Кей ISBN: 978-0-7645-6909-8 Мягкая обложка 960 страниц августа 2004 Посмотреть последнее издание Заголовок –

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