我正在编写一个XSL转换,我无法移动到root并访问其中的每个节点。
假设我在一个上下文中。我有一种情况,我必须去外部节点从那里获取一个值,并返回到相同的上下文。
这是我的XML文件。
<xml version=1.0>
<abc>
<parts>
<part pno="10506">
<pname>Land Before Time I</pname>
<qoh>200</qoh>
<price>19.99</price>
<level>20</level>
</part>
…
</parts>
<orders>
<order ono="1022" takenBy="1001" customer="2222">
<receivedDate>1995-02-13</receivedDate>
<shippedDate>1995-02-20</shippedDate>
<items>
<item>
<partNumber>10601</partNumber>
<quantity>1</quantity>
</item>
<item>
<partNumber>10701</partNumber>
<quantity>1</quantity>
</item>
</items>
</order>
.....
</orders>
</abc>
我在xsl:for-each中的“item”标签内进行迭代,但我想进入“part”标签并获取一个值并返回相同的上下文。
更详细一点:我正在填写一张桌子。我的表有4列:
<part>
获取名称。 (这是我被困的地方)<item>
的子元素。请帮我从零件标签中获取零件名称和价格的值。
以下代码对我不起作用。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet>
<table>
<xsl:param name="param1" />
<xsl:variable name="temp" select ="name(/*)"/>
<xsl:for-each select=".//order[@ono=$param1]/items/item">
<tr>
<td> <xsl:value-of select="$temp//part[@pno=partNumber]/pname"/> </td>
<td> <xsl:value-of select="quantity"/> </td>
<td> <xsl:value-of select="$temp//part[@pno=partNumber]/price"/> </td>
<td> <xsl:value-of select="quantity*$temp//part[@pno=partNumber]/price"/> </td>
</tr>
</xsl:for-each>
</table>
<xsl:stylesheet>
我尝试使用谷歌搜索,但我找不到解决问题的确切方法。我写的代码引发了一些错误。我尝试将“temp”的选择值更改为root(。),但它不起作用。
我只需要一个提示。我不需要答案。只是暗示对我来说已经足够了。
过去5个小时我遇到了这个问题。请回复并帮助我。
答案 0 :(得分:1)
如果要在谓词中引用与当前上下文相关的内容,可以使用current()
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="param1" select="1022" />
<xsl:template match="/">
<table>
<xsl:for-each select="//order[@ono=$param1]/items/item">
<tr>
<td>
<xsl:value-of select="//part[@pno=current()/partNumber]/pname"/>
</td>
<td>
<xsl:value-of select="quantity"/>
</td>
<td>
<xsl:value-of select="//part[@pno=current()/partNumber]/price"/>
</td>
<td>
<xsl:value-of select="quantity * //part[@pno=current()/partNumber]/price"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
然而,更有效的方法是使用密钥。我还清理了一下XSLT,以便更好地使用模板并避免在路径中重复:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="kPart" match="part" use="@pno" />
<xsl:param name="param1" select="1022" />
<xsl:template match="/">
<table>
<xsl:apply-templates select="//order[@ono=$param1]/items/item" />
</table>
</xsl:template>
<xsl:template match="item">
<xsl:variable name="part" select="key('kPart', partNumber)" />
<tr>
<td>
<xsl:value-of select="$part/pname"/>
</td>
<td>
<xsl:value-of select="quantity"/>
</td>
<td>
<xsl:value-of select="$part/price"/>
</td>
<td>
<xsl:value-of select="quantity * $part/price"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
Root不是.
。 Root是/
。如果您想要根元素名称为“part”的任何后代,请使用//part
。
如果您将<xsl:template match="/">
放在<table>
之前并将</xsl:template>
放在</table>
之后,那么当XML解析器解析文档根目录时,XSL处理器将生成您的表格元素。
您的xsl:stylesheet
开放标记需要几个属性。对于XSLT 1.0,它应该是<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
。
我认为这些信息可能足以让你发挥作用。
如果您需要提高效率,则应避免使用//
并使用xsl:key
。您可以找到xsl:key
in the XSL Transformations specification的定义,基础知识和简单示例。