提问人:MAT0718 提问时间:11/5/2023 最后编辑:MAT0718 更新时间:11/5/2023 访问量:57
XSLT 2.0 - 基于条件对节点进行分组和复制 - 错误
XSLT 2.0 - Group and copy nodes based on condition - Error
问:
这是我的源 XML
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>12354</UniqueID>
<ExpenseAmount>998.00</ExpenseAmount>
<Misc>
<Date>2023-10-10-07:00</Date>
<BonusAmount>400.00</BonusAmount>
</Misc>
<Misc>
<Date>2023-10-09-07:00</Date>
<BonusAmount>900.00</BonusAmount>
</Misc>
</Worker>
<Worker>
<UniqueID>4567</UniqueID>
<ExpenseAmount>1507.00</ExpenseAmount>
<Misc>
<Date>2023-10-06-07:00</Date>
<BonusAmount>322.00</BonusAmount>
</Misc>
<Misc>
<Date>2023-10-08-07:00</Date>
<BonusAmount>800.00</BonusAmount>
</Misc>
<Misc>
<Date>2023-10-09-07:00</Date>
<BonusAmount>410.00</BonusAmount>
</Misc>
</Worker>
</Workers>
这是我想做的。
- 整个文档中有 4 个不同的日期,例如 和
2023-10-10-07:00
2023-10-09-07:00
2023-10-06-07:00
2023-10-08-07:00
- 由于我的最终输出应该基于和 4 个不同的
日期在我的源 XML 上,我的预期结果应该有 4 个节点,每个节点都包含对应于
<Date>
<Records>
<Date>
<Worker>
- 但是,有 2 个节点没有任何元素,因此任何没有的节点都应复制到所有节点下
<Worker>
<Date>
<Worker>
<Date>
<Records>
我当前的 XSLT。感谢 michael.hor257k
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Workers">
<Workers>
<xsl:variable name="undated" select="Worker[not(Misc)]"/>
<xsl:variable name="dated" select="Worker[(Misc)]"/>
<xsl:for-each-group select="Worker/Misc" group-by="Date">
<Records>
<xsl:copy-of select="$undated"/>
<xsl:copy-of select="current-group()"/>
</Records>
</xsl:for-each-group>
</Workers>
</xsl:template>
</xsl:stylesheet>
我目前的结果
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Misc>
<Date>2023-10-10-07:00</Date>
<BonusAmount>400.00</BonusAmount>
</Misc>
</Records>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Misc>
<Date>2023-10-09-07:00</Date>
<BonusAmount>900.00</BonusAmount>
</Misc>
<Misc>
<Date>2023-10-09-07:00</Date>
<BonusAmount>410.00</BonusAmount>
</Misc>
</Records>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Misc>
<Date>2023-10-06-07:00</Date>
<BonusAmount>322.00</BonusAmount>
</Misc>
</Records>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Misc>
<Date>2023-10-08-07:00</Date>
<BonusAmount>800.00</BonusAmount>
</Misc>
</Records>
</Workers>
我当前的输出有 4 个节点,但 --> 没有如下所示的父节点,这是不正确的。<Records>
<Misc>
<Date>
<Worker>
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Misc> <!-- Misc should have been under it's <Worker> node -->
<Date>2023-10-10-07:00</Date>
<BonusAmount>400.00</BonusAmount>
</Misc>
</Records>
</Workers>
预期结果
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>12354</UniqueID>
<ExpenseAmount>998.00</ExpenseAmount>
<Misc>
<Date>2023-10-10-07:00</Date>
<BonusAmount>400.00</BonusAmount>
</Misc>
</Worker>
</Records>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>12354</UniqueID>
<ExpenseAmount>998.00</ExpenseAmount>
<Misc>
<Date>2023-10-09-07:00</Date>
<BonusAmount>900.00</BonusAmount>
</Misc>
</Worker>
<Worker>
<UniqueID>4567</UniqueID>
<ExpenseAmount>1507.00</ExpenseAmount>
<Misc>
<Date>2023-10-09-07:00</Date>
<BonusAmount>410.00</BonusAmount>
</Misc>
</Worker>
</Records>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>4567</UniqueID>
<ExpenseAmount>1507.00</ExpenseAmount>
<Misc>
<Date>2023-10-06-07:00</Date>
<BonusAmount>322.00</BonusAmount>
</Misc>
</Worker>
</Records>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>4567</UniqueID>
<ExpenseAmount>1507.00</ExpenseAmount>
<Misc>
<Date>2023-10-08-07:00</Date>
<BonusAmount>800.00</BonusAmount>
</Misc>
</Worker>
</Records>
</Workers>
你能帮我弄清楚这个问题吗?谢谢!
======================================================
仅编辑
以下部分 应用 XSLT 后的结果 michael.hor257k 提供 根据最初提供的源 XML 获取预期结果。但是,在我的源 XML 上,对于相同但不同的下节点,可能有多个节点,如下所示。<Misc>
<Date>
<BonusAmount>
<Worker>
**Source Data**
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>12354</UniqueID>
<ExpenseAmount>998.00</ExpenseAmount>
<Misc>
<Date>2023-10-10-07:00</Date>
<BonusAmount>400.00</BonusAmount> <!-- Amount is 400 here -->
</Misc>
<Misc>
<Date>2023-10-10-07:00</Date>
<BonusAmount>600.00</BonusAmount> <!-- Amount is 600 here -->
</Misc>
</Worker>
</Workers>
XSLT 产生以下结果
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Records>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>12354</UniqueID>
<ExpenseAmount>998.00</ExpenseAmount>
<Misc>
<Date>2023-10-10-07:00</Date>
<BonusAmount>400.00</BonusAmount>
</Misc>
</Worker>
<Worker>
<UniqueID>12354</UniqueID>
<ExpenseAmount>998.00</ExpenseAmount>
<Misc>
<Date>2023-10-10-07:00</Date>
<BonusAmount>600.00</BonusAmount>
</Misc>
</Worker>
</Records>
</Workers>
预期结果如下,两个元素应分组到同一节点下<Misc>
<Worker>
在获得以下结果时,任何帮助都是值得赞赏的。
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Worker>
<UniqueID>67896</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>678965</UniqueID>
<ExpenseAmount>400.00</ExpenseAmount>
<BonusAmount>230.00</BonusAmount>
</Worker>
<Worker>
<UniqueID>12354</UniqueID>
<ExpenseAmount>998.00</ExpenseAmount>
<Misc>
<Date>2023-10-10-07:00</Date>
<BonusAmount>400.00</BonusAmount>
</Misc>
<Misc>
<Date>2023-10-10-07:00</Date>
<BonusAmount>600.00</BonusAmount>
</Misc>
</Worker>
</Workers>
获得预期结果的最终解决方案是
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Workers">
<Workers>
<xsl:variable name="undated" select="Worker[not(Misc)]"/>
<xsl:for-each-group select="Worker/Misc" group-by="Date">
<Records>
<xsl:copy-of select="$undated"/>
<Worker>
<xsl:copy-of select="../(UniqueID | ExpenseAmount)"/>
</Worker>
<xsl:for-each select="current-group()">
<xsl:copy-of select="."/>
</xsl:for-each>
</Records>
</xsl:for-each-group>
</Workers>
</xsl:template>
</xsl:stylesheet>
答:
1赞
michael.hor257k
11/5/2023
#1
试试这种方式:
XSLT 2.0 版
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Workers">
<Workers>
<xsl:variable name="undated" select="Worker[not(Misc)]" />
<xsl:for-each-group select="Worker/Misc" group-by="Date">
<Records>
<xsl:copy-of select="$undated"/>
<xsl:for-each select="current-group()">
<Worker>
<xsl:copy-of select="../(UniqueID|ExpenseAmount)"/>
<xsl:copy-of select="."/>
</Worker>
</xsl:for-each>
</Records>
</xsl:for-each-group>
</Workers>
</xsl:template>
</xsl:stylesheet>
评论
0赞
MAT0718
11/5/2023
非常感谢michael.hor257k,它接近我所期望的。你的代码没有问题。这适用于我最初提供的源 XML,但我的源 XML 也可以有多个 Date',但具有不同的 .我用源 XML、预期结果和当前结果编辑了原始帖子。Misc' element for a same
BonusAmount
0赞
michael.hor257k
11/5/2023
仅当具有相同 Date 的 Misc 元素也具有相同的 UniqueID 和 ExpenseAmount 时,显示的结果才有意义。如果总是如此,那么必要的调整是次要的,您应该能够自己进行。
0赞
MAT0718
11/5/2023
是的,具有相同 Date 的杂项元素将始终具有相同的 UniqueID 和 ExpenseAmount。
0赞
MAT0718
11/5/2023
我得到了我所期望的结果,但有一个小的改变,但由于我的过度思考,我花了一个小时才得到我想要的东西,非常感谢 michael.hor257k。为来这里寻求解决方案的任何其他人发布了解决方案,但我的一个问题是,是复制上述所有元素的唯一方法。我正在尝试一种方法,不专门调用元素,因此尝试复制上面的所有元素,但似乎不起作用。你能给我任何提示,将不胜感激?<xsl:copy-of select="../(UniqueID | ExpenseAmount)"/>
Misc
<xsl:copy-of select="node()"/>
Misc
0赞
michael.hor257k
11/5/2023
您可以使用 .<xsl:copy-of select="../(* except Misc)"/>
评论