XQuery 合并元素和子元素

XQuery to merge elements and children

我正在处理大量 XML 文件,这些文件具有重复的共同元素。我已经能够将它们连接成一个文件并使用 Xquery 进行排序,但我很难采取下一步来根据关键标识符合并元素。例如,我有一个具有以下结构的 XML 文件:

<example>
    <Store ID="111">
        <Manager ID="123">
            <Employee>
                <EmployeeID>0001001</EmployeeID>
                <HireDate Value="1-Jan-2000"/>
                <Action ID="001" Type="S">
                    <Details ID="a1">
                        <TransactionType>I</TransactionType>
                    </Details>
                    <TransactionType>R</TransactionType>
                </Action>
                <TransactionType>R</TransactionType>
            </Employee>
            <TransactionType>R</TransactionType>
        </Manager>
        <TransactionType>R</TransactionType>
    </Store>
    <Store ID="111">
        <Manager ID="123">
            <Employee>
                <EmployeeID>0001001</EmployeeID>
                <HireDate Value="1-Jan-2000"/>
                <Action ID="003" Name="Ecg" Type="S">
                    <Details ID="b1">
                        <TransactionType>I</TransactionType>
                    </Details>
                    <TransactionType>R</TransactionType>
                </Action>
                <TransactionType>R</TransactionType>
            </Employee>
            <TransactionType>R</TransactionType>
        </Manager>
        <TransactionType>R</TransactionType>
    </Store>
    <Store ID="00102">
        <Manager ID="00302">
            <Employee>
                <EmployeeID>0002001</EmployeeID>
                <Sex Value="M"/>
                <Confidential Birthdate="1970-07-03"/>
                <Action ID="003" Name="Ecg" Type="S">
                    <Details ID="c1">
                        <TransactionType>I</TransactionType>
                    </Details>
                    <TransactionType>R</TransactionType>
                </Action>
                <TransactionType>R</TransactionType>
            </Employee>
            <TransactionType>R</TransactionType>
        </Manager>
        <TransactionType>R</TransactionType>
    </Store>
</example>

我希望能够根据 Store ID、Manager ID 的属性值和 EmployeeID 的元素值合并前 2 个主要 Store 元素,这样得到的 XML 如下:

<example>
    <Store ID="111">
        <Manager ID="123">
            <Employee>
                <EmployeeID>0001001</EmployeeID>
                <HireDate Value="1-Jan-2000"/>
                <Action ID="001" Type="S">
                    <Details ID="a1">
                        <TransactionType>I</TransactionType>
                    </Details>
                    <TransactionType>R</TransactionType>
                </Action>
                <Action ID="003" Name="Ecg" Type="S">
                    <Details ID="b1">
                        <TransactionType>I</TransactionType>
                    </Details>
                    <TransactionType>R</TransactionType>
                </Action>
                <TransactionType>R</TransactionType>
            </Employee>
            <TransactionType>R</TransactionType>
        </Manager>
        <TransactionType>R</TransactionType>
    </Store>
    <Store ID="00102">
        <Manager ID="00302">
            <Employee>
                <EmployeeID>0002001</EmployeeID>
                <Sex Value="M"/>
                <Confidential Birthdate="1970-07-03"/>
                <Action ID="003" Name="Ecg" Type="S">
                    <Details ID="c1">
                        <TransactionType>I</TransactionType>
                    </Details>
                    <TransactionType>R</TransactionType>
                </Action>
                <TransactionType>R</TransactionType>
            </Employee>
            <TransactionType>R</TransactionType>
        </Manager>
        <TransactionType>R</TransactionType>
    </Store>
</example>

任何有关实现此结果的 Xquery 方法的建议都将不胜感激 - 或者任何替代方法(例如 XSLT?)。谢谢!

XQuery 1.0 缺少任何分组功能,这使得这很棘手。如果您可以访问 XQuery 3.0,则可以使用新的 "group by" 结构。

与 XSLT 类似,1.0 中没有内置分组功能,但 2.0 中有。使用 XSLT 2.0,您通常会这样做:

<xsl:for-each-group select="Store" 
     group-by="concat(@ID, '/', Manager/@ID), '/', Manager/Employee/EmployeeID">
  <Store ID="{@ID}">
    <Manager ID="{Manager/@ID}">
      <Employee>
        <xsl:variable name="e" select="current-group()/Manager/Employee"/>
        <xsl:copy-of select="($e/EmployeeID)[1]"/>
        <xsl:copy-of select="($e/HireDate)[1]"/>
        <xsl:copy-of select="$e/Action"/>
      </Employee>
    </Manager>
  </Store>
</xsl:for-each-group>

我在这里做了一些假设:你只想要第一个 HireDate,但你想要所有的 Actions。您必须根据您的实际要求对其进行调整。