Как фильтровать узлы в XML с помощью xslt ..? - PullRequest
3 голосов
/ 07 апреля 2011

предположим, у меня есть этот xml:

<college>
    <student>
        <name>amit</name>
        <file>/abc/kk/final.c</file>
        <rollno>22</rollno>
    </student>
    <student>
        <name>sumit</name>
        <file>/abc/kk/up.h</file>
        <rollno>23</rollno>
    </student>
    <student>
        <name>nikhil</name>
        <file>/xyz/up.cpp</file>
        <rollno>24</rollno>
    </student>
    <student>
        <name>bharat</name>
        <file>/abc/kk/down.h</file>
        <rollno>25</rollno>
    </student>
    <student>
        <name>ajay</name>
        <file>/simple/st.h</file>
        <rollno>27</rollno>
    </student>
</college>

Я использую for-each в ".xsl" для отображения всех записей узлов, но я хочу отображать записи только тех узлов, в которых имя файла начинается с "/ abc / kk", поскольку я новичок в xslt ..

Пожалуйста, предоставьте мне решение.

я использую:

<xsl:for-each select="college/student">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="file"/></td>
<td><xsl:value-of select="rollno"/></td>
</tr>

Ответы [ 3 ]

6 голосов
/ 07 апреля 2011

Это преобразование :

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


 <xsl:template match="student[starts-with(file,'/abc/kk')]">
  <tr><xsl:apply-templates/></tr>
 </xsl:template>

 <xsl:template match="student/*">
     <td><xsl:apply-templates/></td>
 </xsl:template>

 <xsl:template match="student"/>    
</xsl:stylesheet>

применительно к предоставленному документу XML:

<college>
    <student>
        <name>amit</name>
        <file>/abc/kk/final.c</file>
        <rollno>22</rollno>
    </student>
    <student>
        <name>sumit</name>
        <file>/abc/kk/up.h</file>
        <rollno>23</rollno>
    </student>
    <student>
        <name>nikhil</name>
        <file>/xyz/up.cpp</file>
        <rollno>24</rollno>
    </student>
    <student>
        <name>bharat</name>
        <file>/abc/kk/down.h</file>
        <rollno>25</rollno>
    </student>
    <student>
        <name>ajay</name>
        <file>/simple/st.h</file>
        <rollno>27</rollno>
    </student>
</college>

дает желаемый, правильный результат:

<tr>
   <td>amit</td>
   <td>/abc/kk/final.c</td>
   <td>22</td>
</tr>
<tr>
   <td>sumit</td>
   <td>/abc/kk/up.h</td>
   <td>23</td>
</tr>
<tr>
   <td>bharat</td>
   <td>/abc/kk/down.h</td>
   <td>25</td>
</tr>

Объяснение

  1. Шаблон, соответствующий любому student, имеющему дочернего элемента file, строковое значение которого начинается с '/ abc / kk' . Это просто помещает сгенерированное содержимое в элемент оболочки tr.

  2. Шаблон, соответствующий любому student, который не имеет тела и эффективно удаляет его (не копирует этот элемент в выходные данные). Этот шаблон имеет более низкий приоритет, чем первый, потому что первый является более конкретным. Поэтому только student элементы, которые не соответствуют первому шаблону, обрабатываются со вторым шаблоном.

  3. Шаблон, соответствующий любому дочернему элементу любого student элемента . Это просто оборачивает содержимое в элемент td.

3 голосов
/ 07 апреля 2011

Вот так:

<xsl:for-each select="college/student[starts-with(file, '/abc/kk')]">
<!-- ... -->

Скобки [ ] разграничивают «фильтр», и внутри этого фильтра вы можете иметь такие функции, как starts-with()

0 голосов
/ 07 апреля 2011

Также вы можете использовать [..] в match:

<xsl:template match="college/student[starts-with(file, '/abc/kk')]">
    <tr>
        <td><xsl:value-of select="name"/></td>
        <td><xsl:value-of select="file"/></td>
        <td><xsl:value-of select="rollno"/></td>
    </tr>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...