XSLT - 删除比较日期的 XML 个节点
XSLT - Delete XML nodes comparing dates
对于下面的 XML,当字段 StartDate 不等于单元 5000 的任何 StartDate 项目时,我需要删除单元 6000 的所有 XML 个节点
我尝试匹配一个模板,但似乎匹配得很好
<?xml version="1.0" encoding="UTF-8"?>
<AllRecords>
<Records>
<Record>
<Items>
<EndDate>2021-03-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST1</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2020-12-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST2</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2020-05-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-02-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST3</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-02-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2020-12-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>2000</company>
<Newplant>TEST4</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2020-01-01T00:00:00.000</StartDate>
<Unit>6000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-03-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>2010</company>
<Newplant>TEST5</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>6000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-06-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>2020</company>
<Newplant>TEST5</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-093T00:00:00.000</StartDate>
<Unit>6000</Unit>
<Status>A</Status>
</Items>
</Record>
</Records>
</AllRecords>
xslt 代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
</xsl:stylesheet>
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="date" select="xs:date(//Items[Status = 'A' and ( Unit=6000)) ]/StartDate
<xsl:template match="$date eq xs:date(//Items[Status = 'A' and Unit='5000']/StartDate)"/>
</xsl:stylesheet>
删除单元 6000 XML 节点后的预期输出 XSLT 代码,因为这 2 个节点的日期与 5000
的 xml 节点中的任何一个都不匹配
<?xml version="1.0" encoding="UTF-8"?>
<AllRecords>
<Records>
<Record>
<Items>
<EndDate>2021-03-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST1</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2020-12-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST2</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2020-05-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-02-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST3</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-03-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>2010</company>
<Newplant>TEST5</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>6000</Unit>
<Status>A</Status>
</Items>
</Record>
</Records>
</AllRecords>
delete all XML nodes of only Unit 6000 when field StartDate is not equal to any of the StartDate items of unit 5000
使用 key:
应该很容易实现
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:strip-space elements="*"/>
<xsl:key name="k1" match="Items[Unit=5000]" use="StartDate" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- remove items that do not have a matching item -->
<xsl:template match="Items[Unit=6000][not(key('k1', StartDate))]"/>
</xsl:stylesheet>
此外 @micheal.hor257k good , this kind of problem can be easyly done with simple XPath/XSLT patterns:
<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="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="Items[Unit=6000][not(StartDate = ../Items[Unit=5000]/StartDate)]"/>
</xsl:stylesheet>
检查一下here
对于下面的 XML,当字段 StartDate 不等于单元 5000 的任何 StartDate 项目时,我需要删除单元 6000 的所有 XML 个节点
我尝试匹配一个模板,但似乎匹配得很好
<?xml version="1.0" encoding="UTF-8"?>
<AllRecords>
<Records>
<Record>
<Items>
<EndDate>2021-03-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST1</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2020-12-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST2</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2020-05-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-02-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST3</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-02-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2020-12-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>2000</company>
<Newplant>TEST4</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2020-01-01T00:00:00.000</StartDate>
<Unit>6000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-03-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>2010</company>
<Newplant>TEST5</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>6000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-06-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>2020</company>
<Newplant>TEST5</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-093T00:00:00.000</StartDate>
<Unit>6000</Unit>
<Status>A</Status>
</Items>
</Record>
</Records>
</AllRecords>
xslt 代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
</xsl:stylesheet>
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="date" select="xs:date(//Items[Status = 'A' and ( Unit=6000)) ]/StartDate
<xsl:template match="$date eq xs:date(//Items[Status = 'A' and Unit='5000']/StartDate)"/>
</xsl:stylesheet>
删除单元 6000 XML 节点后的预期输出 XSLT 代码,因为这 2 个节点的日期与 5000
的 xml 节点中的任何一个都不匹配<?xml version="1.0" encoding="UTF-8"?>
<AllRecords>
<Records>
<Record>
<Items>
<EndDate>2021-03-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST1</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2020-12-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST2</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2020-05-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-02-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>1000</company>
<Newplant>TEST3</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>5000</Unit>
<Status>A</Status>
</Items>
<Items>
<EndDate>2021-03-31T00:00:00.000</EndDate>
<PlantDetails>
<PlantDetailsUS>
<company>2010</company>
<Newplant>TEST5</Newplant>
</PlantDetailsUS>
</PlantDetails>
<StartDate>2021-01-01T00:00:00.000</StartDate>
<Unit>6000</Unit>
<Status>A</Status>
</Items>
</Record>
</Records>
</AllRecords>
delete all XML nodes of only Unit 6000 when field StartDate is not equal to any of the StartDate items of unit 5000
使用 key:
应该很容易实现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:strip-space elements="*"/>
<xsl:key name="k1" match="Items[Unit=5000]" use="StartDate" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- remove items that do not have a matching item -->
<xsl:template match="Items[Unit=6000][not(key('k1', StartDate))]"/>
</xsl:stylesheet>
此外 @micheal.hor257k good
<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="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template
match="Items[Unit=6000][not(StartDate = ../Items[Unit=5000]/StartDate)]"/>
</xsl:stylesheet>
检查一下here