我正在转换XML以生成HTML。
XML
<clause code="section6">
<variable col="1" name="R1C1" row="1">Water</variable>
<variable col="2" name="R1C2" row="1">true</variable>
<variable col="1" name="R2C1" row="2">Gas</variable>
<variable col="2" name="R2C2" row="2"></variable>
<variable col="1" name="R3C1" row="3">Petrol</variable>
<variable col="2" name="R3C2" row="3">true</variable>
<clause>
<clause code="section6">
<variable col="1" name="R1C1" row="1">Water</variable>
<variable col="2" name="R1C2" row="1">true</variable>
<variable col="1" name="R2C1" row="2">Gas</variable>
<variable col="2" name="R2C2" row="2"></variable>
<variable col="1" name="R3C1" row="3">Petrol</variable>
<variable col="2" name="R3C2" row="3">true</variable>
<clause>
XSLT
转换工作正常并显示结果 1)水3)汽油 1: <xsl:for-each select="$clause/variable[@col='1']">
2: <xsl:sort select="@row" data-type="number"/>
3: <xsl:variable name="row-id" select="@row"/>
4: <xsl:variable name="row" select="$clause/variable[@row=$row-id]"/>
5: <xsl:if test="$clause/variable[@col='2' and @row=$row-id]='true'">
6: <xsl:value-of name="row-no" select="concat(position(), ') ')"/>
7: <xsl:value-of select="$clause/variable[@col='1' and @row=$row-id]"/>
8: </xsl:if>
9: </xsl:for-each>
问题是序列号。您可以在第5行过滤器行中看到条件,这些行在 col 2 中只有'true'值,而position()用于显示序列号。我不能在XLST中运行计数器。
我想知道我是否可以在第1行添加第5行的条件。上面示例的结果应该是 1)水2)巡逻任何建议?
答案 0 :(得分:3)
这样做你想要的吗?
我驱动col 2上的for-each选项为true。那样的位置,等于我们在所选节点集中的位置将等于2而不是3
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<xsl:for-each select="clause/variable[@col='2' and text()='true']">
<xsl:sort select="@row" data-type="number"/>
<xsl:variable name="row-id" select="@row"/>
<xsl:value-of select="concat(position(), ') ')"/>
<xsl:value-of select="/clause/variable[@col='1' and @row=$row-id]"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
虽然我可能会使用优先于for-each的模板并使用current(),因此我们不需要row-id变量:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<xsl:apply-templates select="clause/variable[@col='2' and text()='true']">
<xsl:sort select="@row" data-type="number"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="clause/variable[@col='2' and text()='true']">
<xsl:value-of select="concat(position(), ') ')"/>
<xsl:value-of select="/clause/variable[@col='1' and @row=current()/@row]"/>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:2)
我认为你不能用一个XPath 1.0表达式来表达它。
在XSLT 1.0中,我将使用密钥,解决方案变得简短,优雅和高效:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kVarCol2" match="variable[@col=2]" use="@row"/>
<xsl:template match="/*">
<xsl:for-each select="variable[@col='1'][key('kVarCol2', @row)='true']">
<xsl:sort select="@row" data-type="number"/>
<xsl:value-of select="concat('
', position(), ') ', .)"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
当对提供的XML文档应用此转换时(已更正为格式良好):
<clause code="section6">
<variable col="1" name="R1C1" row="1">Water</variable>
<variable col="2" name="R1C2" row="1">true</variable>
<variable col="1" name="R2C1" row="2">Gas</variable>
<variable col="2" name="R2C2" row="2"></variable>
<variable col="1" name="R3C1" row="3">Petrol</variable>
<variable col="2" name="R3C2" row="3">true</variable>
</clause>
产生了想要的正确结果:
1) Water
2) Petrol
<强> II。 XPath 2.0(单表达式)解决方案:
for $i in 1 to max(/*/*/@row/xs:integer(.))
return
/*/variable[@row eq string($i)]
[@col eq '1'
and
../variable
[@row eq string($i)
and
@col eq '2'
and
. eq 'true'
]
]
/concat('
', position(), ') ', .)
在同一个XML文档(上图)上评估此XPath 2.0表达式时,结果是相同的所需字符串:
1) Water
2) Petrol