gpt4 book ai didi

xslt - XSL谓词针对for-each的每次迭代增加

转载 作者:行者123 更新时间:2023-12-03 16:18:25 25 4
gpt4 key购买 nike

快速问题:是否有一种方法可以通过使用变量来递增XPATH的谓词,例如通过C中的数组进行迭代?例如/ XPATH / element [i]

我正在尝试使用XSL使用XPATHS从XML访问数据。 XML是数据库的输出,其中父节点是表名称,子节点是列。 XSL必须能够将子代的文本值转换为具有表名元素的列名的属性。

我试图解决的问题是每个表可以有多个行,这些行作为具有相同名称的兄弟节点输出到XML。任何表中都可能有无限的行,因此我试图对表名的XPATH使用for-each来处理每一行。这行得通,但是当我尝试将文档功能与XPATH一起使用时,谓词先是第一个XPATH,然后是下一个XPATH,然后是下一个,那么我不知道该怎么做。我只能访问第一个XPATH。我想要一种能够在for-each的每次迭代中访问下一个XPATH的方法。有什么可以增加每个循环的谓词,并使用谓词来指向下一个XPATH吗?

下面的XML代码是我用于测试的样本,称为DB.xml:

<?xml version="1.0"?>
<dataset>
<rtbp>
<cfmtype>dog</cfmtype>
<cfmid>1</cfmid>
</rtbp>
<rtbp>
<cfmtype>cat</cfmtype>
<cfmid>2</cfmid>
</rtbp>
<FunctionSet>
<FUNCTIONSET__IDENTIFIER>1</FUNCTIONSET__IDENTIFIER>
<RTBP__CFMID>1</RTBP__CFMID>
</FunctionSet>
<FunctionSet>
<FUNCTIONSET__IDENTIFIER>2</FUNCTIONSET__IDENTIFIER>
<RTBP__CFMID>2</RTBP__CFMID>
</FunctionSet>
</dataset>


以下是我正在使用的XSL:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
<xsl:for-each select="dataset/rtbp">
<xsl:element name="RTBP">
<xsl:attribute name="CFMtype">
<xsl:value-of select="document('DB.xml')/dataset/rtbp[1]/cfmtype" />
</xsl:attribute>
<xsl:attribute name="CFMid">
<xsl:value-of select="document('DB.xml')/dataset/rtbp[1]/cfmid" />
</xsl:attribute>
<xsl:text>&#xa;</xsl:text>

<xsl:for-each select="/dataset/FunctionSet">
<xsl:element name="FunctionSet">
<xsl:attribute name="RTBP__CFMid">
<xsl:value-of select="document('DB.xml')/dataset/FunctionSet[1]/FUNCTIONSET__IDENTIFIER" />
</xsl:attribute>
<xsl:attribute name="RTBP_FunctionSet">
<xsl:value-of select="document('DB.xml')/dataset/FunctionSet[1]/RTBP__CFMID" />
</xsl:attribute>
</xsl:element>
<xsl:text>&#xa;</xsl:text>
</xsl:for-each>

</xsl:element>
<xsl:text>&#xa;</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>


谓词目前设置为1,但我希望它是在每个循环上迭代的变量,以便XPATH更改为表名的下一个出现。

预期结果如下:

<?xml version="1.0"?>
<RTBP CFMtype="dog" CFMid="1">
<FunctionSet RTBP__CFMid="1" RTBP_FunctionSet="1"/>
</RTBP>
<RTBP CFMtype="cat" CFMid="2">
<FunctionSet RTBP__CFMid="2" RTBP_FunctionSet="2"/>
</RTBP>


如您所知,第二个表(FunctionSet)是第一个表(RTBP)的子表,因此for-each位于for-each内部。我需要一种方法,将FunctionSet的第一行放入RTBP的第一行,第二行也是如此。

我是XML,XSL和发布问题的新手。

最佳答案

目的是从平面XML重新创建分层XML。
使用DBunit从数据库导出。关联可以完成
通过cmfid


您绝对应该基于匹配cfmid值的键-特别是如果您期望大量的行。尝试:

XSLT 1.0

<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:key name="func" match="FunctionSet" use="RTBP__CFMID" />

<xsl:template match="/">
<root>
<xsl:for-each select="dataset/rtbp">
<RTBP CFMtype="{cfmtype}" CFMid="{cfmid}">
<xsl:for-each select="key('func', cfmid)">
<FunctionSet RTBP__CFMid="{RTBP__CFMID}" RTBP_FunctionSet="{FUNCTIONSET__IDENTIFIER}"/>
</xsl:for-each>
</RTBP>
</xsl:for-each>
</root>
</xsl:template>

</xsl:stylesheet>


将以上内容应用于以下测试输入时:

<?xml version="1.0"?>
<dataset>
<rtbp>
<cfmtype>dog</cfmtype>
<cfmid>124</cfmid>
</rtbp>
<rtbp>
<cfmtype>cat</cfmtype>
<cfmid>256</cfmid>
</rtbp>
<FunctionSet>
<FUNCTIONSET__IDENTIFIER>Canine</FUNCTIONSET__IDENTIFIER>
<RTBP__CFMID>124</RTBP__CFMID>
</FunctionSet>
<FunctionSet>
<FUNCTIONSET__IDENTIFIER>Feline</FUNCTIONSET__IDENTIFIER>
<RTBP__CFMID>256</RTBP__CFMID>
</FunctionSet>
<FunctionSet>
<FUNCTIONSET__IDENTIFIER>Hound</FUNCTIONSET__IDENTIFIER>
<RTBP__CFMID>124</RTBP__CFMID>
</FunctionSet>
</dataset>


结果是:

<?xml version="1.0" encoding="utf-8"?>
<root>
<RTBP CFMtype="dog" CFMid="124">
<FunctionSet RTBP__CFMid="124" RTBP_FunctionSet="Canine"/>
<FunctionSet RTBP__CFMid="124" RTBP_FunctionSet="Hound"/>
</RTBP>
<RTBP CFMtype="cat" CFMid="256">
<FunctionSet RTBP__CFMid="256" RTBP_FunctionSet="Feline"/>
</RTBP>
</root>


请注意,您请求的输出格式不必要在父级和子级中都复制 cfmid值。

关于xslt - XSL谓词针对for-each的每次迭代增加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23649814/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com