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。您必须根据您的实际要求对其进行调整。
我正在处理大量 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。您必须根据您的实际要求对其进行调整。