【发布时间】:2020-06-18 23:31:40
【问题描述】:
有没有比两个“for-loops”更好的方法来为以下 XML 数据集/XML 结构组装节点元素?
<?xml version="1.0" encoding="UTF-8"?>
<root>
<nodeA>
<nodeAa>
<Row>
<ID>100001</ID>
<NAME>ABC</NAME>
<EDV_NUMBER>900001</EDV_NUMBER>
</Row>
<Row>
<ID>100002</ID>
<NAME>DEF</NAME>
<EDV_NUMBER>900002</EDV_NUMBER>
</Row>
<Row>
<ID>700003</ID>
<NAME>XYZ</NAME>
<EDV_NUMBER>900002</EDV_NUMBER>
</Row>
</nodeAa>
</nodeA>
<nodeB>
<nodeBa>
<Row>
<EDV_NUMBER>900001</EDV_NUMBER>
<TYP>002</TYP>
<Row>
<EDV_NUMBER>900002</EDV_NUMBER>
<TYP>002</TYP>
</Row>
<Row>
<EDV_NUMBER>900002</EDV_NUMBER>
<TYP>009</TYP>
</Row>
</nodeBa>
</nodeB>
</root>
输出文件应包含节点“//nodeBa/Row/*”的所有元素,包括节点“//nodeAa/Row/”的元素(ID & NAME),其中元素“EDV_NUMBER”是相同的。
<?xml version="1.0" encoding="UTF-8"?>
<CSV>
<Row>
<EDV_NUMBER>900001</EDV_NUMBER>
<TYP>002</TYP>
<ID>100001</ID>
<NAME>ABC</NAME>
</Row>
<Row>
<EDV_NUMBER>900002</EDV_NUMBER>
<TYP>002</TYP>
<ID>100002</ID>
<NAME>DEF</NAME>
</Row>
<Row>
<EDV_NUMBER>900002</EDV_NUMBER>
<TYP>009</TYP>
<ID>700003</ID>
<NAME>XYZ</NAME>
</Row>
</CSV>
可以使用以下代码生成输出,但不适用于大数据集:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="#all" version="2.0">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="/">
<CSV>
<xsl:for-each select="/root/nodeB/nodeBa/Row">
<xsl:variable name="FIBU" select="./EDV_NUMBER/text()"/>
<xsl:variable name="TYP" select="./TYP/text()"/>
<Row select="{position()}">
<xsl:copy-of select="./*"/>
<xsl:for-each select="/root/nodeA/nodeAa/Row">
<xsl:variable name="counter" select="position()"/>
<xsl:choose>
<xsl:when test="/root/nodeA/nodeAa/Row[$counter]/EDV_NUMMER/text()=$FIBU and $TYP='002' and /root/nodeA/nodeAa/Row[$counter]/TYP/text() < '700000'">
<xsl:copy-of select="./ID"/>
<xsl:copy-of select="./NAME"/>
</xsl:when>
<xsl:when test="/root/nodeA/nodeAa/Row[$counter]/EDV_NUMMER/text()=$FIBU and $TYP='009' and /root/nodeA/nodeAa/Row[$counter]/TYP/text() >= '700000'">
<xsl:copy-of select="./ID"/>
<xsl:copy-of select="./NAME"/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:for-each>
</Row>
</xsl:for-each>
</CSV>
</xsl:template>
</xsl:stylesheet>
【问题讨论】: