2012-06-07 64 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

我已经扩展了我的答案,希望能够尝试并多解释一下,以及'*/*'的含义。 –