XSLT 2.0:基于条件对节点进行分组和复制

XSLT 2.0 : Group and Copy Nodes based on a condition

提问人:MAT0718 提问时间:11/3/2023 最后编辑:MAT0718 更新时间:11/4/2023 访问量:58

问:

这是我的源 XML

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
    <Worker>
        <UniqueID>67896</UniqueID>
        <ExpenseAmount>400.00</ExpenseAmount>
        <BonusAmount>230.00</BonusAmount>
    </Worker>
    <Worker>
        <UniqueID>567899</UniqueID>
        <ExpenseAmount>190.00</ExpenseAmount>
        <BonusAmount>2000.00</BonusAmount>
    </Worker>
    <Worker>
        <UniqueID>12354</UniqueID>
        <Date>2023-10-06-07:00</Date>
        <ExpenseAmount>998.00</ExpenseAmount>
        <BonusAmount>400.00</BonusAmount>
    </Worker>
    <Worker>
        <UniqueID>12354</UniqueID>
        <Date>2023-10-10-07:00</Date>
        <ExpenseAmount>998.00</ExpenseAmount>
        <BonusAmount>400.00</BonusAmount>
    </Worker>    
    <Worker>
        <UniqueID>4567</UniqueID>
        <Date>2023-10-06-07:00</Date>
        <ExpenseAmount>1507.00</ExpenseAmount>
        <BonusAmount>322.00</BonusAmount>
    </Worker>
    <Worker>
        <UniqueID>4567</UniqueID>
        <Date>2023-10-10-07:00</Date>
        <ExpenseAmount>1507.00</ExpenseAmount>
        <BonusAmount>322.00</BonusAmount>
    </Worker>
</Workers>

预期输出

根据唯一值对节点进行分组,并复制所有没有元素的节点以及具有唯一值的节点<Date><Date><Date>

    <?xml version="1.0" encoding="UTF-8"?>
<Workers>
    <Records>
        <Worker> <!-- This node doesnt have <Date> element -->
            <UniqueID>67896</UniqueID> 
            <ExpenseAmount>400.00</ExpenseAmount>
            <BonusAmount>230.00</BonusAmount>
        </Worker>
        <Worker><!-- This node doesnt have <Date> element  -->
            <UniqueID>567899</UniqueID>
            <ExpenseAmount>190.00</ExpenseAmount>
            <BonusAmount>2000.00</BonusAmount>
        </Worker>
        <Worker>  <!--  <Date> value is unique 2023-10-06-07:00 -->
            <UniqueID>12354</UniqueID> 
            <Date>2023-10-06-07:00</Date>
            <ExpenseAmount>998.00</ExpenseAmount>
            <BonusAmount>400.00</BonusAmount>
        </Worker>
        <Worker>  <!--  <Date> value is unique 2023-10-06-07:00 -->
            <UniqueID>4567</UniqueID>
            <Date>2023-10-06-07:00</Date>
            <ExpenseAmount>1507.00</ExpenseAmount>
            <BonusAmount>322.00</BonusAmount>
        </Worker>        
    </Records>
    <Records>
        <Worker> <!-- This node needs to repeat as it does'nt have <Date> element -->
            <UniqueID>67896</UniqueID> 
            <ExpenseAmount>400.00</ExpenseAmount>
            <BonusAmount>230.00</BonusAmount>
        </Worker>
        <Worker> <!-- This node needs to repeat as it does'nt have <Date> element -->
            <UniqueID>567899</UniqueID>
            <ExpenseAmount>190.00</ExpenseAmount>
            <BonusAmount>2000.00</BonusAmount>
        </Worker>
        <Worker> <!--  <Date> value is unique 2023-10-06-07:00 -->
            <UniqueID>12354</UniqueID>
            <Date>2023-10-10-07:00</Date>
            <ExpenseAmount>998.00</ExpenseAmount>
            <BonusAmount>400.00</BonusAmount>
        </Worker>   
        <Worker> <!--  <Date> value is unique 2023-10-06-07:00 -->
            <UniqueID>4567</UniqueID>
            <Date>2023-10-10-07:00</Date>
            <ExpenseAmount>1507.00</ExpenseAmount>
            <BonusAmount>322.00</BonusAmount>
        </Worker>        
    </Records>
</Workers>

第一个 <Records> 节点 - 具有值的节点,并与另一个值为 4567 和 2023-10-06-07:00 的节点一起放置<Worker><UniqueID>67896567899<Worker><UniqueID><Date>

我当前的 XSLT

    <?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:output method="xml" indent="yes"/>
    <xsl:template match="Workers">
        
            <xsl:copy>
                <Records>
                    <xsl:copy-of select="Worker[not(exists(Date))]"/>
                    <xsl:for-each-group select="Worker[exists(Date)]" group-by="Date">                       
                        <xsl:copy>
                            <xsl:copy-of select="current-group()[exists(Date)]"/>
                        </xsl:copy>
                    </xsl:for-each-group>
                </Records>
            </xsl:copy>        
    </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>567899</UniqueID>
         <ExpenseAmount>190.00</ExpenseAmount>
         <BonusAmount>2000.00</BonusAmount>
      </Worker>
      <Worker>
         <Worker>
            <UniqueID>12354</UniqueID>
            <Date>2023-10-06-07:00</Date>
            <ExpenseAmount>998.00</ExpenseAmount>
            <BonusAmount>400.00</BonusAmount>
         </Worker>
         <Worker>
            <UniqueID>4567</UniqueID>
            <Date>2023-10-06-07:00</Date>
            <ExpenseAmount>1507.00</ExpenseAmount>
            <BonusAmount>322.00</BonusAmount>
         </Worker>
      </Worker>
      <Worker>
         <Worker>
            <UniqueID>12354</UniqueID>
            <Date>2023-10-10-07:00</Date>
            <ExpenseAmount>998.00</ExpenseAmount>
            <BonusAmount>400.00</BonusAmount>
         </Worker>
         <Worker>
            <UniqueID>4567</UniqueID>
            <Date>2023-10-10-07:00</Date>
            <ExpenseAmount>1507.00</ExpenseAmount>
            <BonusAmount>322.00</BonusAmount>
         </Worker>
      </Worker>
   </Records>
</Workers>

问题

具有唯一值的节点不会与预期输出中的节点一起复制。<Date><Worker>

任何人都可以看看并帮助我了解我应该做什么才能获得所需的输出。

谢谢

XSLT XSLT-2.0

评论

0赞 michael.hor257k 11/4/2023
为什么您的预期输出有两个元素(看起来相同)?Records
0赞 michael.hor257k 11/4/2023
另外,两个元素可以有相同但不同的吗?如果是这样,那么结果应该是什么样子?WorkerDateUniqueID
0赞 MAT0718 11/4/2023
嗨@michael.hor257k,元素的唯一值为 ,第一个 2023-10-06-07:00',第二个元素的值为 2023-10-10-07:00。Records<Date>Records' element has a date RecordsDate
0赞 MAT0718 11/4/2023
yes - 如源 XML 中提供的那样,两个元素可以具有相同的元素,例如 值 12354 和 4567 具有相同的 .WorkerDateUniqueIDDate
0赞 MAT0718 11/4/2023
前两个应该从源 XML 示例重复,因为这两个节点不包含 Worker 节点不包含具有唯一日期的 Worker' 节点。由于源上有两个唯一的日期,因此需要创建两个元素。WorkerWorkerDate' field. So Date' element needs to be copied along with Records

答:

1赞 michael.hor257k 11/4/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(Date)]" />
        <xsl:for-each-group select="Worker" 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>

评论

0赞 MAT0718 11/4/2023
谢谢@michael.hor257k。例如,如果源 XML 中有 5 个不同的日期值,则应创建 5 个节点,并且每个节点应包含具有相同元素值的节点。第二个条件是,没有元素的节点应该存在于所有 5 个 .因此,在我的源 XML 中,有两个不同的日期,例如 AND 所以我的结果 XML 应该有两个节点。每个 Record 节点都应具有具有唯一日期的 Worker 节点以及没有“Date”的节点RecordsRecordWorkerDateWorkerDateRecords2023-10-06-07:002023-10-10-07:00RecordsWorker
0赞 michael.hor257k 11/4/2023
我相信这正是我的代码所做的。
0赞 MAT0718 11/5/2023
嗨,michael.hor257k - 先生,我不得不创建一个新问题,因为我在当前节点上面临的一个问题,因为 XML 的结构与我最初认为的略有不同。如果你有时间,你能看看这个吗?谢谢!stackoverflow.com/questions/77424407/......