【问题标题】:how to filter nodes in xml using xslt..?如何使用 xslt.. 过滤 xml 中的节点?
【发布时间】:2011-04-07 09:06:33
【问题描述】:

假设我有这个 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>

我在“.xsl”中使用 for-each 来显示节点的所有条目,但我只想显示那些文件名以“/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>

【问题讨论】:

  • 请提供格式正确的 XML,以便我们更好地理解您的问题
  • 好问题,+1。有关使用 XSLT 的基本功能(例如模板和推送样式处理)的完整、简短且简单的解决方案,请参阅我的答案。提供了详细的解释。

标签: xslt


【解决方案1】:

这种转变

<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 元素中。

【讨论】:

    【解决方案2】:

    像这样:

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

    方括号[ ] 界定了一个“过滤器”,在该过滤器内您可以拥有starts-with() 之类的功能

    【讨论】:

    • @kuldeep:请检查此答案是否正确。它将帮助您让更多人愿意回答您关于 SO 的进一步问题。
    【解决方案3】:

    您也可以在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>
    

    【讨论】:

      猜你喜欢
      • 2018-04-19
      • 2019-11-06
      • 2010-11-20
      • 1970-01-01
      • 2012-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多