如何处理XPath和XSL中的层级关系和比较?

问题描述

我正在尝试使用XSL从XML文档中提取信息并将其显示在HTML页面中。 首先,XML的示例结构:

<warehouses>
   <warehouse>
      <id>1</id>
      <name>Florida</name>
      <address>
         <country>US</country>
      </address>
      <items>
         <item>
            <id>1</id>
            <qty>30</qty>
            <name>coke</name>
         </item>
         <item>
            <id>2</id>
            <qty>40</qty>
            <name>pie</name>
         </item>
         .........   # more <item> not being presented like Orange
      </items>
   </warehouse>
   ......   # more <warehouse> located in varIoUs countries not being presented
</warehouses>

基本上,标签<warehouse>下有许多不同的<warehouses><item>中有许多<items>

我现在要做的是提供美国或加拿大仓库的名称 ,以及与所有项目相比数量最多的可用项目的名称在那个特定的仓库中输出一个HTML表。喜欢:

|Florida           |    Orange    |
|British Columbia  |  Canada Dry  |

注意:XML根据每个项目的ID(而非数量)对<item>进行排序。因此,尽管仅由于空间限制而仅在此处打印可乐和派,但还有很多其他材料(例如橙色)没有显示出来。

当前,我可以显示国家/地区部分,但无法显示产品名称。具体来说,第二列中没有输出

|Florida           |       |
|British Columbia  |       |

由于XML是给定的文件,没有错误,因此应归因于错误的XSL。

我的XSL代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
<xsl:template match="/">
  <html>
  <body>
  <table border="1">
<xsl:apply-templates select="/warehouses/warehouse[address/country='US' or address/country='Canada']"/><br />
</table>
  </body>
  </html>
</xsl:template>
 
<xsl:template match="/warehouses/warehouse[address/country='US' or address/country='Canada']">
<tr>  
<td>
  <xsl:apply-templates select="name"/><br/>
</td>
<td>
  <xsl:apply-templates select="items"/>
  </td>
</tr>
</xsl:template>
 
<xsl:template match="name">
  <xsl:value-of select="."/>
</xsl:template>
 
<xsl:template match="items">
  <xsl:value-of select="self/item[qty=max(/parent::*/item/qty)]/name"/><br />
</xsl:template>
 
</xsl:stylesheet>

我认为,这主要是由于在<xsl:template match="items">下出现了我的冗余和错误的XPath,因为:

  1. 它涉及各种父节点和子节点,例如<items><item><qty>
  2. 我认为甚至max()函数的使用方式都不正确……

有人会帮助我,非常感谢!

解决方法

与该特定仓库中的所有物品相比,数量最多的可用物品的名称

我们可以说这是<item>,在同一个父项下,<item>在{Path}中较小,而在<qty>中则没有items/item[not(qty &lt; ../item/qty)]

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

  <xsl:template match="/">
    <html>
      <body>
        <table border="1">
          <xsl:apply-templates select="warehouses/warehouse[address/country[.='US' or .='Canada']]"/>
        </table>
      </body>
    </html>
  </xsl:template>
   
  <xsl:template match="warehouse">
    <tr>  
      <td>
        <xsl:apply-templates select="name"/>
      </td>
      <td>
        <xsl:apply-templates select="(items/item[not(qty &lt; ../item/qty)])[1]/name" />
      </td>
    </tr>
  </xsl:template>
   
  <xsl:template match="name">
    <xsl:value-of select="." />
  </xsl:template>

</xsl:stylesheet>

由于总是有两个项目具有相同的<qty>,在这种情况下都将被打印,因此我将其明确地限制为上面的第一个项目。

<xsl:template match="name">既可以使用<warehouse>名称也可以使用<item>名称。

样本的输出为

<html>
  <body>
    <table border="1">
      <tr>
        <td>Florida</td>
        <td>pie</td>
      </tr>
    </table>
  </body>
</html>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...