2011-08-19 184 views
2

XSLT過濾節點我有一個源XML如下: -條件邏輯

<StudentSet> 
<Student> 
    <StudentName>Kapil</StudentName> 
    <Subject>English</Subject> 
    <Subject>History</Subject> 
    <Subject>Mathematics</Subject> 
    <Subject>Economics</Subject> 
</Student> 
<Student> 
    <StudentName>Atul</StudentName> 
    <Subject>English</Subject> 
    <Subject>History</Subject> 
    <Subject>Economics</Subject> 
</Student> 
<Student> 
    <StudentName>Nisha</StudentName> 
    <Subject>English</Subject> 
    <Subject>History</Subject> 
</Student> 
<Student> 
    <StudentName>Manish</StudentName> 
</Student> 
</StudentSet> 

要施加的規則如下。

1)如果學生在數學,顯示學生姓名和數學

2)錄取如果學生在經濟學就讀,但不是數學,顯示學生姓名和經濟

3)如果學生既沒有參加數學和經濟學,也沒有選擇學生的姓名和任何一個科目。

4)如果學生沒有註冊任何科目,請不要選擇該學生。

我希望得到以下的輸出: -

<StudentSet> 
<Student> 
    <StudentName>Kapil</StudentName> 
    <Subject>Mathematics</Subject> 
</Student> 
<Student> 
    <StudentName>Atul</StudentName> 
    <Subject>Economics</Subject> 
</Student> 
<Student> 
    <StudentName>Nisha</StudentName> 
    <Subject>English</Subject> 
</Student> 
</StudentSet> 

任何人可以幫助哪些XSLT可以用於這個好嗎?

+2

這是功課?這對我來說似乎是一個家庭作業問題。 –

+0

您應該發佈您已有的XSLT代碼... –

+0

我是XSLT的新手。我使用的是完全錯誤的。我正在使用變量並試圖在for-each循環中更改變量的值。谷歌搜索後,我發現它不可能改變xslt中的變量值。所以那個不好。 – Kapil

回答

4

最簡單的方法就是使用模板與謂詞,像這樣:

<xsl:template match="Student[Subject='Economics']"> 
    <!-- Handle economics students --> 
</xsl:template> 

<xsl:template match="Student[Subject='Mathematics']"> 
    <!-- Handle maths students --> 
    <!-- overrides maths+econ students, as it comes later --> 
</xsl:template> 

<xsl:template match="Student[not(Subject='Economics') and not(Subject='Mathematics')]"> 
    <!-- Handle other students. Use 'Subject[1]' to refer to first subject --> 
</xsl:template> 

<!-- Handle students with no subject, outputting nothing. --> 
<xsl:template match="Student[not(Subject)]" /> 

在每一種情況下,你可能想要做

<xsl:copy> <!-- copies the 'Student' element --> 
    <xsl:copy-of select="StudentName" /> 
    <xsl:copy-of select="Subject[text()='subjectname']" /> 
    <!-- or --> 
    <xsl:copy-of select="Subject[1]" /> <!-- first subject in list --> 
</xsl:copy> 

有一個更短,更有效的方式,但它的有點難以理解的初學者:

<xsl:template match="Student[Subject='Mathematics']/Subject[not(text()='Mathematics')]" /> 
<xsl:template match="Student[Subject='Economics' and not(Subject='Mathematics')]/Subject[not(text()='Economics')]" /> 
<xsl:template match="Student[not(Subject='Economics') and not(Subject='Mathematics')]/Subject[position() != 1]" /> 
<xsl:template match="Student[not(Subject)]" /> 

這些做的是描述元素th在不應該輸出。例如,第一個元素找到任何具有數學主題的元素,並且在該元素中找到任何沒有「數學」文本的元素Subject。模板匹配這些節點,並不輸出任何內容。你可以用一個這樣的大模板規則來做到這一點:

<xsl:template match=" 
    Student[Subject='Mathematics']/Subject[not(text()='Mathematics')] 
| Student[Subject='Economics' and not(Subject='Mathematics')]/Subject[not(text()='Economics')] 
| Student[not(Subject='Economics') and not(Subject='Mathematics')]/Subject[position() != 1] 
| Student[not(Subject)] 
    " /> 

雖然它開始變得不那麼可讀。

0

這是一個簡單的解決方案,可與任意數量的優先主題的作品,並且只使用固定大小它可以很容易地用於更困難的問題作爲一個模板:「顯示只能從第一k科目的N科目「優先級列表:

<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:param name="vSubs" select="'x|Economics|Mathematics|'"/> 

<xsl:template match="Student[Subject]"> 
    <Student> 
     <xsl:copy-of select="StudentName"/> 

     <xsl:for-each select="Subject"> 
     <xsl:sort 
     select="string-length(substring-before($vSubs, 
               concat('|',.,'|') 
               ) 
          )" 
     data-type="number" order="descending"/> 
     <xsl:if test="position()=1"> 
     <xsl:copy-of select="."/> 
     </xsl:if> 
     </xsl:for-each> 
    </Student> 
</xsl:template> 

<xsl:template match="text()"/> 
</xsl:stylesheet> 

當所提供的XML文檔應用:

<StudentSet> 
    <Student> 
     <StudentName>Kapil</StudentName> 
     <Subject>English</Subject> 
     <Subject>History</Subject> 
     <Subject>Mathematics</Subject> 
     <Subject>Economics</Subject> 
    </Student> 
    <Student> 
     <StudentName>Atul</StudentName> 
     <Subject>English</Subject> 
     <Subject>History</Subject> 
     <Subject>Economics</Subject> 
    </Student> 
    <Student> 
     <StudentName>Nisha</StudentName> 
     <Subject>English</Subject> 
     <Subject>History</Subject> 
    </Student> 
    <Student> 
     <StudentName>Manish</StudentName> 
    </Student> 
</StudentSet> 

想要的,正確的結果產生

<Student> 
    <StudentName>Kapil</StudentName> 
    <Subject>Mathematics</Subject> 
</Student> 
<Student> 
    <StudentName>Atul</StudentName> 
    <Subject>Economics</Subject> 
</Student> 
<Student> 
    <StudentName>Nisha</StudentName> 
    <Subject>English</Subject> 
</Student>