我的XML文件中有三个表:tableX
,tableA
和tableB
。
这是我的算法:
tableX
的每个行元素并检查Xelement1
是否为NULL
(空)。tableA
中的每一行,并将行元素Aelement2
的值与Xelement2
的另一行元素tableX
进行比较。tableB
的每个行元素,并将Belement1
的行元素tableB
的值与Aelement1
的行元素tableA
的值进行比较Belement2
tableB
的值
目前我正在这样做并且正在运作:
<xsl:for-each select="/root/table[@name='tableX']/row">
<xsl:variable name="rec" select="."/>
<xsl:choose>
<xsl:when test="Xelement1=''">
<xsl:for-each select="/root/table[@name='tableA']/row">
<xsl:variable name="member" select="."/>
<xsl:if test="Aelement2=$rec/Xelement2">
<xsl:for-each select="/root/table[@name='tableB']/row">
<xsl:if test="Belement1=$member/Aelement1">
<xsl:value-of select="Belement2"/> 
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<!-- Xelement1 is not null -->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
但是,我希望我可以访问,例如第三个Aelement1
循环中的for-each
,无需将其保存到变量member
。
另外,为什么这不起作用?
[...]
<xsl:for-each select="/root/table[@name='tableA']/row">
<xsl:variable name="member" select="Aelement1"/>
<xsl:if test="Aelement2=$rec/Xelement2">
<xsl:for-each select="/root/table[@name='tableB']/row">
<xsl:if test="Belement1=$member">
<xsl:value-of select="Belement2"/> 
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
[...]
最小但完整的XML示例:
<root>
<table name="tableX">
<row>
<Xelement1>11</Xelement1>
<Xelement2>3</Xelement2>
<Xother>failure</Xother>
</row>
<row>
<Xelement1>NULL</Xelement1>
<Xelement2>9</Xelement2>
<Xother>success</Xother>
</row>
</table>
<table name="tableA">
<row>
<Aelement1>10</Aelement1>
<Aelement2>16</Aelement2>
<Aother>failure</Aother>
</row>
<row>
<Aelement1>12</Aelement1>
<Aelement2>9</Aelement2>
<Aother>success</Aother>
</row>
<row>
<Aelement1>12</Aelement1>
<Aelement2>16</Aelement2>
<Aother>failure</Aother>
</row>
<row>
<Aelement1>14</Aelement1>
<Aelement2>9</Aelement2>
<Aother>success</Aother>
</row>
</table>
<table name="tableB">
<row>
<Belement1>10</Belement1>
<Belement2>failure</Belement2>
<Bother>random</Bother>
</row>
<row>
<Belement1>12</Belement1>
<Belement2>success</Belement2>
<Bother>random</Bother>
</row>
<row>
<Belement1>14</Belement1>
<Belement2>success</Belement2>
<Bother>random</Bother>
</row>
</table>
</root>
答案 0 :(得分:1)
我会定义一个键
<xsl:key name="row" match="table[@name = 'tableB']/row" use="Belement"/>
然后你可以缩短
<xsl:for-each select="/root/table[@name='tableA']/row">
<xsl:variable name="member" select="."/>
<xsl:for-each select="/root/table[@name='tableB']/row">
<xsl:if test="Belement=$member/Aelement">
<!--Do something-->
</xsl:if>
</xsl:for-each>
</xsl:for-each>
到
<xsl:for-each select="/root/table[@name='tableA']/row/key('row', Aelement)">
<!--Do something-->
</xsl:for-each>
关于术语,您的代码会处理row
elements
或row
element nodes
。
对于不起作用的样本,您需要向我们展示最少但完整的XML输入样本,XSLT代码,您想要的结果,以及我们可以轻松重现问题的结果。
答案 1 :(得分:1)
您应该能够使用单个XPath表达式从表B中选择相应的行:
<xsl:for-each select="/root/table[@name = 'tableB']/row[
Belement = /root/table[@name = 'tableA']/row/Aelement
]">
<!-- Do something -->
</xsl:for-each>
这是因为XPath的=
在节点集上运行时,将左侧的所有节点与右侧的所有节点进行比较(就像SQL中的INNER JOIN一样) )。
它将在您的示例中选择一个节点(即具有<row>
的{{1}}),但如果有更多匹配则会选择更多节点。
在对问题进行实质性编辑之后,XPath表达式变得更加复杂。同样的原则也适用。
<Belement>5</Belement>
将从您的样本中选择包含//table[@name = 'tableB']/row[
Belement1 = //table[@name = 'tableA']/row[
Aelement2 = //table[@name = 'tableX']/row[
Xelement1 = 'NULL'
]/Xelement2
]/Aelement1
]/Belement2
的元素。
从里到外阅读:
"success"
行tableX
,您需要Xelement1 = 'NULL'
Xelement2
行tableA
对应您想要的Aelement2
Aelement1
行tableB
对应您想要的Belement1
答案 2 :(得分:1)
另外,为什么这不起作用?
> <xsl:for-each select="/root/table[@name='tableA']/row">
> <xsl:variable name="member" select="Aelement"/>
> <xsl:for-each select="/root/table[@name='tableB']/row">
> <xsl:if test="Belement=$member">
> <!--Do something-->
> </xsl:if>
> </xsl:for-each>
> </xsl:for-each>
实际上,确实有效。如果您尝试使用tableB中的匹配行实际执行某些操作,例如:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<output>
<xsl:for-each select="/root/table[@name='tableA']/row">
<xsl:variable name="member" select="Aelement"/>
<xsl:for-each select="/root/table[@name='tableB']/row">
<xsl:if test="Belement=$member">
<!--Do something-->
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
您将收到:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<row>
<Belement>5</Belement>
</row>
</output>