1

我刚刚开始学习 XML 和 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 中显示它。我不明白为什么。

据我了解,它正在选择“root”的所有孙元素,如下所示:

根/商店/人

但为什么亚历克西斯没有重复呢?只有布莱克重复了……

4

1 回答 1

1

在您的匹配模板中,您<xsl:apply-templates/>将选择第一个shopperson元素。关于person元素,没有特定的模板,因此 XSLT 将继续匹配其子元素并为“Blake”挑选员工

但是,商店有一个匹配的模板,问题确实在于您在匹配它的模板中所做的事情。

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

因为您已经启动了 xpath 表达式,/root所以它将相对于文档的根元素开始计算,而不是您当前定位的shop元素。这意味着它将选择元素/root/shop/person/root/person/employee导致您的重复“Blake”。但是,由于您没有在其他地方匹配 '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>
于 2012-06-07T06:30:38.570 回答