我有点难以从简单的结构化XML中获取数量的最大值。所以需要一些帮助!
我的XML如下:
<?xml version="1.0" encoding="utf-8"?>
<TANK_DETAILS>
<TABLES>
<OUTPUT>
<item>
<AREA>INDIA</AREA>
<MACHINE>T100</MACHINE>
<MATERIAL>1111111</MATERIAL>
<BATCH>100</BATCH>
<QTY>18815.000</QTY>
</item>
<item>
<AREA>INDIA</AREA>
<MACHINE>T102</MACHINE>
<MATERIAL>1111111</MATERIAL>
<BATCH>200</BATCH>
<QTY>100.000</QTY>
</item>
<item>
<AREA>INDIA</AREA>
<MACHINE>T103</MACHINE>
<MATERIAL>1111111</MATERIAL>
<BATCH>300</BATCH>
<QTY>10000.000</QTY>
</item>
<item>
<AREA>INDIA</AREA>
<MACHINE>T101</MACHINE>
<MATERIAL>1111111</MATERIAL>
<BATCH>400</BATCH>
<QTY>35550.000</QTY>
</item>
<item>
<AREA>INDIA</AREA>
<MACHINE>T104</MACHINE>
<MATERIAL>1111111</MATERIAL>
<BATCH>500</BATCH>
<QTY>10100.000</QTY>
</item>
</OUTPUT>
</TABLES>
</TANK_DETAILS>
我想得到<MACHINE>,<BATCH> & <Qty>
<QTY>
最大的地方。
输出 XML 应如下所示:
<Rowsets>
<Rowset>
<Row>
<MACHINE>T101</MACHINE>
<BATCH>400</BATCH>
<QTY>35550.000</QTY>
</Row>
</Rowset>
</Rowsets>
我正在尝试的 XSLT 如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!-- Putting the maximum QTY from the list into a variable -->
<xsl:variable name="max-QTY">
<xsl:call-template name="find-max">
<!-- Select the list of QTY elements -->
<xsl:with-param name="QTY" select="//*[contains(local-name(), 'QTY')]"/>
</xsl:call-template>
</xsl:variable>
<xsl:template match="*">
<!-- Displaying the result -->
<QTY>
<xsl:value-of select="$max-QTY"/>
</QTY>
</xsl:template>
<!-- This template works recursively on the list of QTY. -->
<xsl:template name="find-max">
<xsl:param name="QTY"/>
<!-- The value of the first QTY in this list. -->
<xsl:variable name="this-QTY">
<xsl:value-of select="$QTY[position() = 1]"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$QTY">
<!-- The maximum value of the remaining QTY in this list. -->
<xsl:variable name="other-QTY">
<xsl:call-template name="find-max">
<xsl:with-param name="QTY" select="$QTY[position() != 1]"/>
</xsl:call-template>
</xsl:variable>
<!-- Return the maximum of this QTYand the remaining QTY. -->
<xsl:choose>
<xsl:when test="$other-QTY> $this-QTY">
<xsl:value-of select="$other-QTY"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$this-QTY"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- We've reached the last QTY in the list. -->
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
我得到的输出是:
<?xml version="1.0" encoding="utf-8"?>
<QTY>35550.000</QTY>
所以我能够找到最大<QTY>
但我正在努力获得最大<QTY>
的相应<MACHINE> & <BATCH>
。
我确定我犯了一个小错误,但我非常卡住并面临编码人员的障碍。
另外,如果有更好的方法来找到最大值,请提供最佳答案。那将是有帮助的。
谢谢。
我只需按QTY
对item
进行排序,然后输出第一个(按降序排序)或最后一个(按升序排序顺序):
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="TABLES">
<Rowsets>
<Rowset>
<xsl:for-each select="OUTPUT/item">
<xsl:sort select="QTY" data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<Row>
<xsl:copy-of select="MACHINE | BATCH | QTY"/>
</Row>
</xsl:if>
</xsl:for-each>
</Rowset>
</Rowsets>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/94hvTz2 有一个在线样本。
我会从有一个键开始,比如:
<xsl:key name="kQTY" match="QTY" use="."/>
然后,我将最大数量存储在一个变量中,例如:
<xsl:variable name="maxQTY">
<xsl:for-each select="//item">
<xsl:sort select="key('kQTY', QTY)" order="descending"/>
<xsl:if test="position()=1">
<xsl:value-of select="QTY"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
然后,在与OUTPUT
节点匹配的模板中,我将筛选包含最大数量的项目,例如:
<xsl:template match="OUTPUT">
<Rowset>
<xsl:apply-templates select="item[QTY=$maxQTY]"/>
</Rowset>
</xsl:template>
然后需要一个模板来过滤项目内容:
<xsl:template match="item">
<xsl:apply-templates select="MACHINE,BATCH,QTY"/>
</xsl:template>
一些用于清理的匹配模板
<xsl:template match="TANK_DETAILS">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="TABLES">
<Rowsets>
<xsl:apply-templates/>
</Rowsets>
</xsl:template>
和标识模板:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
整个样式表如下:
<?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"
exclude-result-prefixes="xs"
version="2.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kQTY" match="QTY" use="."/>
<xsl:variable name="maxQTY">
<xsl:for-each select="//item">
<xsl:sort select="key('kQTY', QTY)" order="descending"/>
<xsl:if test="position()=1">
<xsl:value-of select="QTY"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OUTPUT">
<Rowset>
<xsl:apply-templates select="item[QTY=$maxQTY]"/>
</Rowset>
</xsl:template>
<xsl:template match="item">
<xsl:apply-templates select="MACHINE,BATCH,QTY"/>
</xsl:template>
<xsl:template match="TANK_DETAILS">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="TABLES">
<Rowsets>
<xsl:apply-templates/>
</Rowsets>
</xsl:template>
</xsl:stylesheet>
在这里看到它的实际效果。