2013-05-20 2 views
1

У меня есть файл XML в древовидной структуре, как этот final.xmlФильтр дерева с помощью XSLT

<?xml version="1.0"?> 
<?xml-stylesheet type="text/xsl" href="b.xsl"?> 
<childrens> 
<child_1 entity_id="1" value="Root Catalog" parent_id="0"> 
    <child_2 entity_id="2" value="Navigate" parent_id="1"> 
     <child_4 entity_id="4" value="Activities" parent_id="2"> 
      <child_10066 entity_id="10066" value="Physical1" parent_id="4"> 
       <child_10067 entity_id="10067" value="Cricket" parent_id="10066"> 
        <child_10068 entity_id="10068" value="One Day" parent_id="10067"/> 
       </child_10067> 
      </child_10066> 
      <child_10069 entity_id="10069" value="Test2" parent_id="4"/> 
      <child_10070 entity_id="10070" value="Test3" parent_id="4"/> 
      <child_10071 entity_id="10071" value="Test4" parent_id="4"/> 
      <child_10072 entity_id="10072" value="Test5" parent_id="4"/> 
      <child_5 entity_id="5" value="Physical" parent_id="4"/> 
     </child_4> 
     <child_4331 entity_id="4331" value="Region" parent_id="2"> 
      . 
      . 
      . 
      . 
     </child_4331> 
    </child_2> 
</child_1> 
</childrens> 

вот мой код XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:template match="*" mode="item"> 
     <li> 
      <xsl:value-of select="@value"/> 
      <xsl:apply-templates select="current()[*]"/> 
     </li> 
</xsl:template> 

    <xsl:template match="*/*/*"> 
    <ul> 
     <xsl:apply-templates select="*[1] | node()[current()/ancestor::*[3]]" mode="item"/> 
    <xsl:if test="local-name(child::*) = 'child_4'"><div id="Activity"></div></xsl:if> 
    </ul> 
    </xsl:template> 
</xsl:stylesheet> 

и у меня есть еще один файл XML, который содержит идентификатор листовой узел я хочу, чтобы отобразить только тот узел, который находится в файле filter.xml (с родительским идентификатором)

и filter.xml является

<products> 
    <product_id value="1"> 
    <tab_id value="351"> 
     <tab_name value="test1"/> 
     <dist_activity value="5"/> 
     <dist_activity value="10068"/> 
     <dist_activity value="10070"/> 
    </tab_id> 
    </product_id> 
    <product_id value="2"> 
    <tab_id value="352"> 
     <tab_name value="test2"/> 
     <dist_activity value="10069"/> 
    </tab_id> 
    </product_id> 
</products> 

Здесь dist_activity содержит идентификатор листового узла, который является entity_id в основном XML-файле, поэтому я хочу вывод с использованием этого 2 xml-файла. В настоящее время я использую только основные XML-файл не в filter.xml файл здесь мой выходной ток и из положить, который я хочу, используя как файл

enter image description here

здесь находится в filter.xml за один день (10068), Test2 (10069), test3 (10070), Physical (5), поэтому я хочу только те, что есть в моем дереве

, так какие изменения мне нужно сделать в моем xslt код ???

ответ

1

Не совсем ясно (для меня), как фильтр должен работать. Из вашего заявления:
здесь в filter.xml за один день (10068), test2 (10069), TEST3 (10070), физический (5), так что я хочу только тех, кто в моем дереве
и filter.xml Я ожидаю: Вам нравится иметь li элементов в вашем представлении для элементов child_xxxx, где entity_id self или потомка существует как @ значение dist_activity в файле filter.xml.

Поэтому попробуйте это небольшое изменение в вашей XLST:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:variable name="filter" select="document('iz1_filter.xml')"/> 

    <xsl:template match="*" mode="item"> 
     <xsl:if test="$filter//dist_activity[@value= current()/descendant-or-self::*/@entity_id ]" > 
      <li> 
       <xsl:value-of select="@value"/> 
       <xsl:apply-templates select="current()[*]"/> 
      </li> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="*/*/*"> 
     <ul> 
      <xsl:apply-templates select="*[1] | node()[current()/ancestor::*[3]]" mode="item"/> 
      <xsl:if test="local-name(child::*) = 'child_4'"> 
       <div id="Activity"></div> 
      </xsl:if> 
     </ul> 
    </xsl:template> 
</xsl:stylesheet> 

Какой будет генерировать следующий вывод:

<ul> 
    <li> 
     Activities<ul> 
      <li> 
       Physical1<ul> 
        <li> 
         Cricket<ul> 
          <li>One Day</li> 
         </ul> 
        </li> 
       </ul> 
      </li> 
      <li>Test2</li> 
      <li>Test3</li> 
      <li>Physical</li> 
     </ul> 
    </li> 
    <div id="Activity"></div> 
</ul> 
0

node()[current()/ancestor::*[3]] выбирает все дочерние узлы как минимум с тремя предками. Поскольку текущий узел имеет двух родителей, все его дети имеют три предка, гарантированных.

Если вы хотите выбрать только трех предыдущих братьев и сестер, попробуйте ось preceding-sibling, а не ось ancestor.

+0

я хочу, чтобы результат usnig 'filter.xml' –

+0

может у меня есть код, пожалуйста ?? –

+0

Это то, что вы на самом деле хотите? Если вам просто нужны первые три элемента, почему бы не 'select =" node() [position() <4] "?? – apmasell

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