如何使用xsl获取xml文件的所有元素值

时间:2014-06-10 17:22:12

标签: xml xslt nodes traversal

我正在尝试遍历xml文件并在html页面中查看其元素。我的问题是它只接受第一个节点的值而不会转到下一个节点。另外我不知道如何以更一般的方式使用每个节点的元素,比如使用name()函数而不是每个元素或属性的名称,就像在我的代码中一样,有没有办法呢?因为我做了一些尝试,但他们没有工作......

XSL FILE:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
  <html><body><h2> Car Model Info </h2>
  <table border="1">
    <xsl:apply-templates mode="elem" select="/*"/>
  </table></body>
  </html>
</xsl:template>
<xsl:template mode="elem" match="/*">
  <tr bgcolor="#9acd32" ><th colspan = "12"><xsl:value-of select="name()"/></th></tr>
  <tr><xsl:apply-templates mode="parent" select="/*/*"/></tr>
  <tr><xsl:apply-templates mode="attr" select="/*/*/@*"/></tr>
  <tr><xsl:apply-templates mode="attr_val" select="/*/*/@*"/></tr>
  <tr><xsl:apply-templates mode="child" select="/*/*/*"/></tr>
  <tr><xsl:apply-templates mode="child_val" select="/*/*"/></tr> 
</xsl:template>

<xsl:template mode="parent" match="/*/*">
  <th colspan="4"><xsl:value-of select="name()"/></th>
</xsl:template>
<xsl:template mode="attr" match="/*/*/@*">
  <th><xsl:value-of select="name()"/>(a)</th>
</xsl:template>
<xsl:template mode="child" match="/*/*/*">
  <th><xsl:value-of select="name()"/>(c)</th>
</xsl:template>

<xsl:template mode="attr_val" match="/*/*/@*">
  <xsl:for-each select = "/*/*">
  <td><xsl:value-of select="//*/@model"/></td>
  <td><xsl:value-of select="/*/*/@year"/></td>
  <td><xsl:value-of select="/*/*/@starting_price"/></td>
  <td><xsl:value-of select="/*/*/@doors"/></td>
  </xsl:for-each>
</xsl:template>

<xsl:template mode="child_val" match="/*/*">
  <xsl:for-each select = "/*/*">
  <td><xsl:value-of select="//type"/></td>
  <td><xsl:value-of select="//horse_power"/></td>
  <td><xsl:value-of select="//drivetrain"/></td>
  <td><xsl:value-of select="//transmission"/></td>
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="html_xml.xsl"?>
<CarModel>
<Audi model = "TT" year = "2006" starting_price = "33.000$" doors = "2">
    <type>sport</type>
    <horse_power>222hp</horse_power>
    <drivetrain>quattro</drivetrain>
    <transmission>6_Manual</transmission>
</Audi>
<Mercedes model = "W222_S400" year = "2013" starting_price = "63.000$" doors = "4">
    <type>luxury</type>
    <horse_power>302hp</horse_power>
    <drivetrain>front_wheel_drive</drivetrain>
    <transmission>7_Automatic</transmission>
</Mercedes>
<BMW model = "X3_xDrive35i" year = "2010" staring_price = "40.000$" doors = "4">
    <type>crossover_SUV</type>
    <horse_power>302hp</horse_power>
    <drivetrain>quattro</drivetrain>
    <transmission>6_Manual</transmission>
</BMW>
</CarModel>

输出:

<html>
<body>
<h2> Car Model Info </h2>
<table border="1">
<tr bgcolor="#9acd32">
<th colspan="12">CarModel</th>
</tr>
<tr>
<th colspan="4">Audi</th><th colspan="4">Mercedes</th><th colspan="4">BMW</th>
</tr>
<tr>
<th>model(a)</th><th>year(a)</th><th>starting_price(a)</th><th>doors(a)</th><th>model(a)</th><th>year(a)</th><th>starting_price(a)</th><th>doors(a)</th><th>model(a)</th><th>year(a)</th><th>staring_price(a)</th><th>doors(a)</th>
</tr>
<tr>
<td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td><td>TT</td><td>2006</td><td>33.000$</td><td>2</td>
</tr>
<tr>
<th>type(c)</th><th>horse_power(c)</th><th>drivetrain(c)</th><th>transmission(c)</th><th>type(c)</th><th>horse_power(c)</th><th>drivetrain(c)</th><th>transmission(c)</th><th>type(c)</th><th>horse_power(c)</th><th>drivetrain(c)</th><th>transmission(c)</th>
</tr>
<tr>
<td>sport</td><td>222hp</td><td>quattro</td><td>6_Manual</td><td>sport</td><td>222hp</td><td>quattro</td><td>6_Manual</td><td>sport</td><td>222hp</td><td>quattro</td><td>6_Manual</td><td>sport</td><td>222hp</td><td>quattro</td><td>6_Manual</td><td>sport</td><td>222hp</td><td>quattro</td><td>6_Manual</td><td>sport</td><td>222hp</td><td>quattro</td><td>6_Manual</td><td>sport</td><td>222hp</td><td>quattro</td><td>6_Manual</td><td>sport</td><td>222hp</td><td>quattro</td><td>6_Manual</td><td>sport</td><td>222hp</td><td>quattro</td><td>6_Manual</td>
</tr>
</table>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

主要问题是您使用/甚至//在模板内部启动路径,这样您始终可以从根节点分别选择文档节点。因此,仅使用相对路径来执行

<xsl:template mode="child_val" match="/*/*">
  <td><xsl:value-of select="type"/></td>

这样,模板输出模板的context元素的type元素。对于那种类型的XSLT代码,不需要将for-each与模板混合,如果您想遍历文档只需编写模板并使用apply-templates来保持处理,这样您就可以到达所有节点和有模块化代码。