我有一个包含游戏数据的xml文件,这是一个.exe下载;游戏名称;图像位置和要使用的备用文本。哪个被分类到catagorys。 (见下文)
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="games.xsl"?>
<all>
<general>
<catagory_name>
<catg_1>Action</catg_1>
<catg_2>Other</catg_2>
</catagory_name>
</general>
<games>
<catagory name='Action'>
<game>
<name>1945<!--name--></name>
<url><!--URL to game download--></url>
<image><!--image location--></image>
<alt>1945 Icon<!--alt text for image--></alt>
</game>
</catagory>
<catagory name='Other'>
<game>
<name>Platform Game<!--name--></name>
<url><!--URL to game download--></url>
<image><!--image location--></image>
<alt>Platform Game Icon<!--alt text for image--></alt>
</game>
</catagory>
</games>
</all>
然后我得到这个xslt文件将xml转换为xhtml ...
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/all">
<html>
<body>
<h1 style="text-align:center;">Games</h1>
<center>
<table>
<xsl:if test="//general/catagory_name/catg_1">
<xsl:variable name="catg">
<xsl:value-of select="//general/catagory_name/catg_1"/>
</xsl:variable>
<xsl:if test="//games/catagory[@name=$catg]/game[position() = (1)]/url">
<tr>
<td colspan="4" rowspan="1">
<h2>
<xsl:copy-of select="$catg"/>
</h2>
</td>
</tr>
<xsl:for-each select="//games/catagory[@name=$catg]/game[position() mod 4 = 1]">
<xsl:variable name="pos" select="position() * 4"/>
<tr>
<xsl:if test="//games/catagory[@name=$catg]/game[position() = ($pos - 3)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 3)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 3)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 3)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg]/game[position() = ($pos - 2)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 2)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 2)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 2)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg]/game[position() = ($pos - 1)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 1)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 1)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 1)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg]/game[position() = ($pos)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
</tr>
<tr>
<xsl:if test="//games/catagory[@name=$catg]/game[position() = ($pos - 3)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 3)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg]/game[position() = ($pos -3)]/name"/>
</p>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg]/game[position() = ($pos - 2)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 2)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg]/game[position() = ($pos -2)]/name"/>
</p>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg]/game[position() = ($pos - 1)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos - 1)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg]/game[position() = ($pos -1)]/name"/>
</p>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg]/game[position() = ($pos)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg]/game[position() = ($pos)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg]/game[position() = ($pos)]/name"/>
</p>
</a>
</td>
</xsl:if>
</tr>
</xsl:for-each>
</xsl:if>
</xsl:if>
<xsl:if test="//general/catagory_name/catg_2">
<xsl:variable name="catg2">
<xsl:value-of select="//general/catagory_name/catg_2"/>
</xsl:variable>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = (1)]/url">
<tr>
<td colspan="4" rowspan="1">
<h2>
<xsl:copy-of select="$catg2"/>
</h2>
</td>
</tr>
<xsl:for-each select="//games/catagory[@name=$catg2]/game[position() mod 4 = 1]">
<xsl:variable name="pos" select="position() * 4"/>
<tr>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
</tr>
<tr>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg2]/game[position() = ($pos -3)]/name"/>
</p>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg2]/game[position() = ($pos -2)]/name"/>
</p>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg2]/game[position() = ($pos -1)]/name"/>
</p>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg2]/game[position() = ($pos)]/name"/>
</p>
</a>
</td>
</xsl:if>
</tr>
</xsl:for-each>
</xsl:if>
</xsl:if>
</table>
</center>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
这段代码非常合适,但已经很复杂了。首先,它检查特定类别是否存在,然后该类别是否包含任何游戏。然后它显示它,但仅在数据存在时显示。所以你会很高兴这一切都很好。我的问题是,每次我想添加一个新的类别我必须进入xslt文件,并添加下面的代码与变量$ catg被称为$ catg1,$ catg2等所有我需要的catagorys因为你可以不要改变现有变量的值。
<xsl:if test="//general/catagory_name/catg_2">
<xsl:variable name="catg2">
<xsl:value-of select="//general/catagory_name/catg_2"/>
</xsl:variable>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = (1)]/url">
<tr>
<td colspan="4" rowspan="1">
<h2>
<xsl:copy-of select="$catg2"/>
</h2>
</td>
</tr>
<xsl:for-each select="//games/catagory[@name=$catg2]/game[position() mod 4 = 1]">
<xsl:variable name="pos" select="position() * 4"/>
<tr>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos)]/url)"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos)]/image)"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos)]/alt)"/>
</xsl:attribute>
</img>
</a>
</td>
</xsl:if>
</tr>
<tr>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 3)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg2]/game[position() = ($pos -3)]/name"/>
</p>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 2)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg2]/game[position() = ($pos -2)]/name"/>
</p>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos - 1)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg2]/game[position() = ($pos -1)]/name"/>
</p>
</a>
</td>
</xsl:if>
<xsl:if test="//games/catagory[@name=$catg2]/game[position() = ($pos)]/url">
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="normalize-space(//games/catagory[@name=$catg2]/game[position() = ($pos)]/url)"/>
</xsl:attribute>
<p>
<xsl:value-of select="//games/catagory[@name=$catg2]/game[position() = ($pos)]/name"/>
</p>
</a>
</td>
</xsl:if>
</tr>
</xsl:for-each>
</xsl:if>
</xsl:if>
我想要做的是能够为每个人使用一个,所以只需要有一个代码(上面),但是复杂,从来不需要改变一个新的类别。所以我的问题是我该怎么做?我尝试过变量等,但是每次你想要一个新的类别时你仍然需要编辑代码,因为你无法改变现有变量的值。
我能想到的唯一解决方案是将$ catg替换为它所代表的节点值,即general / catagory_name / catg并每次循环它但我没有取得任何成功。
答案 0 :(得分:2)
标题中问题的简单答案是“你不能”。 XSLT变量有点错误命名,因为它们在创建后无法更改。
有两种样式的XSLT,您试图以过程方式使用XSLT,样式表处于控制状态,您可以从输入文档中“提取”所需的数据。这通常与XSLT的预期用法背道而驰,XSLT本质上更具说明性。 “push”样式依赖于XSLT进程自然地读取输入XML并将您感兴趣的事件交给您,这些事件是由匹配模板定义的。一个简单的Google search on "xslt push vs pull"将为您提供大量信息。
对于非常简单的样式表,pull-style通常会产生更短的代码,但是随着复杂性的增加(如在您的情况下),推送样式可以更容易阅读和理解,假设您了解XSLT处理流程的工作原理。我已经看到过XSLT如何处理输入的最佳解释可以在Evan Lenz的“XSLT 1.0 Pocket Reference”中找到(我与O'Reilly或Lenz先生没有联系)。 Wikipedia article on XSLT也很好地涵盖了基础知识。
从程序思维到XSLT需要进行重大调整,但一旦你体验到“啊哈!”时刻并学会以声明的方式思考,一切都变得简单得多。
答案 1 :(得分:1)
使用OL从1开始编号。
选择每个类别,无论重复的值如何。
确定这是第一次出现的类别,第一个游戏的ID,以及同一类别中首个游戏的ID。
如果这是第一次出现的类别,只需为每个游戏应用模板,并将祖先作为给定类别。对每个类别使用li,并使用类和CSS来实现类似表格的安排。
添加排序以实现排序输出...
<xsl:template name="categoryList">
<ol>
<xsl:for-each select="//game/ancestor::category">
<xsl:sort select="@name" />
<xsl:variable name="name" select="@name"/>
<xsl:variable name="gameid1" select="generate-id(game[1])"/>
<xsl:variable name="gameidFirst" select="generate-id(//game[ancestor::category[@name=$name]][1])"/>
<xsl:if test="$gameid1=$gameidFirst">
<li><xsl:value-of select="@name"/>
<xsl:apply-templates select="//game[ancestor::category[@name=$name]]">
<xsl:sort select="name/text()"/>
</xsl:apply-templates>
</li>
</xsl:if>
</xsl:for-each>
</ol>
</xsl:template>
<xsl:template match="game">
<div>
Name:<span class="name"><xsl:value-of select="name"/></span>,
URL:<span class="url"><xsl:value-of select="url"/></span>,
Image:<span class="image"><xsl:value-of select="image"/></span>,
</div>
</xsl:template>