2012-06-07 61 views
1

我剛開始學習XML & XSLT並對Xpath有一個簡短的問題。XSLT Xpath通配符

這裏的XML代碼:

<root> 

<shop> 
    <person> 
     <employee> 
      <name> Alexis </name> 
      <role> Manager </role> 
      <task> Sales </task> 
     </employee> 
    </person> 
</shop> 

<person> 
    <employee> 
     <role> Supervisor </role> 
     <name> Blake </name> 
     <task> Control </task> 
    </employee> 
</person> 


</root> 

和這裏的XSLT代碼:

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="root"> 
<html><head></head> 
<body><xsl:apply-templates/> 
</body> 
</html> 
</xsl:template> 


<xsl:template match="shop"> 
<xsl:apply-templates select="/root/*/*"/> 
</xsl:template> 

<xsl:template match="employee"> 
<u> <xsl:apply-templates select="name"/> </u> 
(Task: <xsl:apply-templates select="task"/>) 
<br></br> 
</xsl:template> 

<xsl:template match="person2"> 
<xsl:apply-templates /> 
</xsl:template> 

</xsl:stylesheet> 

輸出是:

Alexis (Task: Sales) 
Blake (Task: Control) 
Blake (Task: Control) 

我不明白爲什麼最後一部分是重複的?我知道,這是由於XSLT這部分代碼:

<xsl:apply-templates select="/root/*/*"/> 

但那只是因爲我是用代碼擺弄周圍,並在Firefox中顯示它。我不明白爲什麼。

從我的理解,它的選擇所有孫子「根」的元素,就像這樣:

根/店/人

但爲什麼不亞歷克西斯重複呢?只有布雷克重複...

回答

1

在你匹配的模板,你做<xsl:apply-templates/>將先挑元素。關於元素,沒有爲這個特定的模板,所以XSLT將繼續以匹配其子元素,拿起員工爲「布雷克」

然而,有一個匹配店鋪的模板,並且問題確實與您在與之相匹配的模板中所做的操作有關。

<xsl:apply-templates select="/root/*/*"/> 

因爲你已經與/root開始XPath表達式,這將開始mathing相對於文檔的根元素,而不是您目前定位在元素。這意味着它將選擇導致重複'Blake'的元素/root/shop/person/root/person/employee。但是,由於您在其他地方與「Alexis」的員工元素不匹配,因此僅輸出一次。

你可能需要做的只是此相反,在員工元素

<xsl:apply-templates select="*/*"/> 

匹配這將匹配當前元素的所有盛大的孩子。 *將匹配子元素,因此*/*將匹配子元素的子元素。但是,如果意圖僅輸出僱員元素,則可以通過利用元素的默認模板匹配行爲處理其子元素的事實來簡化您的XSLT。試試這個XSLT:

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

    <xsl:template match="root"> 
     <html> 
     <head/> 
     <body> 
      <xsl:apply-templates/> 
     </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="employee"> 
     <u> 
     <xsl:value-of select="name"/> 
     </u> 
     <xsl:value-of select="concat(' (Task:', task, ')')"/> 
     <br/> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您的XML,下面是輸出

<html> 
    <head> 
    </head> 
    <body> 
     <u> Alexis </u> (Task: Sales)<br> 
     <u> Blake </u> (Task: Control)<br> 
    </body> 
</html> 
+0

+1尼斯解釋和替代樣式表。 –

+0

非常感謝您的回覆! 我不想讓它只顯示員工或任何東西,它只是一個我想了解的考試問題。 我瞭解你: /根/店/人及/根/人/員工 但由於員工的人對於這部分孩子: /根/店/人/員工 那麼爲什麼Alexis也不是重複輸出的一部分嗎? 此外,這是做什麼*/* ?? – shadowz1337

+0

我已經擴展了我的答案,希望能夠嘗試並多解釋一下,以及'*/*'的含義。 –