根据不同的子模式通过XLST过滤XML

问题描述 投票:0回答:1

我有一个包含用户的 xml,每天可以进行多次更改 - 这是由序列号表示的。因此我有以下 XML:

<userValues>
    <user>
        <ID>1</ID>
        <startDate>20241013</startDate>
        <someValue>200</someValue>
        <sequenceNr>1</sequenceNr>
    </user>
    <user>
        <ID>1</ID>
        <startDate>20241013</startDate>
        <someValue>500</someValue>
        <sequenceNr>2</sequenceNr>
    </user>
    <user>
        <ID>2</ID>
        <startDate>20241001</startDate>
        <someValue>200</someValue>
        <sequenceNr>1</sequenceNr>
    </user>
    <user>
        <ID>3</ID>
        <startDate>20241001</startDate>
        <someValue>200</someValue>
        <sequenceNr>1</sequenceNr>
    </user>
</userValues>

这需要过滤,所以我得到以下结果:

<userValues>
    <user>
        <ID>1</ID>
        <startDate>20241013</startDate>
        <someValue>500</someValue>
        <sequenceNr>2</sequenceNr>
    </user>
    <user>
        <ID>2</ID>
        <startDate>20241001</startDate>
        <someValue>200</someValue>
        <sequenceNr>1</sequenceNr>
    </user>
    <user>
        <ID>3</ID>
        <startDate>20241001</startDate>
        <someValue>200</someValue>
        <sequenceNr>1</sequenceNr>
    </user>
</userValues>

所以基本上我需要为每个用户提供最高的序列号 - 但说实话,我什至不确定 XSLT 是否可以为我做到这一点(但如果可能的话会节省大量编码)

在进入 XSLT 处理之前,我可以获取按 ID、startDate 和equenceNr 排序的 XML。

因为我还不太了解 XSLT(基本上我现在开始学习它......)我想知道它是否可能,如果可以的话,如何实现?

xml xslt
1个回答
0
投票

请尝试以下基于 XSLT 2.0 及更高版本的解决方案。

输入XML

<userValues>
    <user>
        <ID>1</ID>
        <startDate>20241013</startDate>
        <someValue>200</someValue>
        <sequenceNr>1</sequenceNr>
    </user>
    <user>
        <ID>1</ID>
        <startDate>20241013</startDate>
        <someValue>500</someValue>
        <sequenceNr>2</sequenceNr>
    </user>
    <user>
        <ID>2</ID>
        <startDate>20241001</startDate>
        <someValue>200</someValue>
        <sequenceNr>1</sequenceNr>
    </user>
    <user>
        <ID>3</ID>
        <startDate>20241001</startDate>
        <someValue>200</someValue>
        <sequenceNr>1</sequenceNr>
    </user>
</userValues>

XSLT 2.0

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output indent="yes" method="xml" encoding="utf-8"
                omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/userValues">
        <xsl:copy>
            <xsl:for-each-group select="user" group-by="ID">
                <xsl:variable name="max-sequenceNr"
                              select="max(current-group()/sequenceNr/xs:int(.))"/>
                <xsl:copy-of select="current-group()[sequenceNr=$max-sequenceNr]"/>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出XML

<userValues>
  <user>
    <ID>1</ID>
    <startDate>20241013</startDate>
    <someValue>500</someValue>
    <sequenceNr>2</sequenceNr>
  </user>
  <user>
    <ID>2</ID>
    <startDate>20241001</startDate>
    <someValue>200</someValue>
    <sequenceNr>1</sequenceNr>
  </user>
  <user>
    <ID>3</ID>
    <startDate>20241001</startDate>
    <someValue>200</someValue>
    <sequenceNr>1</sequenceNr>
  </user>
</userValues>
© www.soinside.com 2019 - 2024. All rights reserved.