使用 XSLT 删除重复节点 [英] Remove duplicate node using XSLT

查看:25
本文介绍了使用 XSLT 删除重复节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从以下源 XML 中删除重复项.

I am trying to remove duplicates from the below source XML.

要求 1 中, 只会出现一次,但 会重复.我需要删除 的组合已经出现一次的情况.在此示例中,需要删除 的第 3 次和第 4 次出现.

Requirement 1 Inside <ns0:Message1>, <UpdateMultipleObjectsOperationsSchema> will only come once, but <sObject> will repeat. I need to remove the cases where the combination of <AccountId> and <ContactId> has already appeared once. In this example, 3rd and 4th occurrence of <sObject> needs to be removed.

要求 2 中, 可能会重复 100 次. 下不需要值或子标记.我想删除所有重复项,只保留第一次出现在这里.

Requirement 2 Inside <ns0:Message2>, <UpdateMultipleObjectsOperationsSchema/> may repeat 100's of times. No values or sub tags are expected under <UpdateMultipleObjectsOperationsSchema/>. I want to remove all duplicates and keep only the first occurrence here.

XML 代码

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
   <ns0:Message1>
      <UpdateMultipleObjectsOperationsSchema>
         <AccountContactRole>
            <Operation>Create</Operation>
            <ObjectType>ACRObject</ObjectType>
            <TransactionLevel>REQUIRED</TransactionLevel>
            <sObjects>
               <sObject>
                  <AccountId>A12345</AccountId>
                  <ContactId>C001</ContactId>
                  <Role>SalesPerson</Role>
               </sObject>
               <sObject>
                  <AccountId>A12345</AccountId>
                  <ContactId>C002</ContactId>
                  <Role>SalesPerson</Role>
               </sObject>
               <sObject>
                  <AccountId>A12345</AccountId>
                  <ContactId>C002</ContactId>
                  <Role>SalesPerson</Role>
               </sObject>
               <sObject>
                  <AccountId>A12345</AccountId>
                  <ContactId>C002</ContactId>
                  <Role>SalesPerson</Role>
               </sObject>
            </sObjects>
         </AccountContactRole>
      </UpdateMultipleObjectsOperationsSchema>
   </ns0:Message1>
   <ns0:Message2>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
      <UpdateMultipleObjectsOperationsSchema/>
   </ns0:Message2>
</ns0:Messages>

预期产出

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
   <ns0:Message1>
      <UpdateMultipleObjectsOperationsSchema>
         <AccountContactRole>
            <Operation>Create</Operation>
            <ObjectType>ACRObject</ObjectType>
            <TransactionLevel>REQUIRED</TransactionLevel>
            <sObjects>
               <sObject>
                  <AccountId>A12345</AccountId>
                  <ContactId>C001</ContactId>
                  <Role>SalesPerson</Role>
               </sObject>
               <sObject>
                  <AccountId>A12345</AccountId>
                  <ContactId>C002</ContactId>
                  <Role>SalesPerson</Role>
               </sObject>
            </sObjects>
         </AccountContactRole>
      </UpdateMultipleObjectsOperationsSchema>
   </ns0:Message1>
   <ns0:Message2>
      <UpdateMultipleObjectsOperationsSchema/>
   </ns0:Message2>
</ns0:Messages>

我是 XSL 的新手,有点卡住了.任何帮助都非常感谢.

I am new to XSL and am kind of stuck. Any help is truly appreciated.

这是我尝试过的...对于第一个要求(参考这里的一些帖子后)

请原谅我缺乏 XSL 知识:(

Excuse my lack of knowledge in XSL :(

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
  xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="trip-tth" match="/ns0:Messages/ns0:Message1/UpdateMultipleObjectsOperationsSchema/AccountContactRole/sObjects/sObject" use="concat(AccountId, '+', ContactId)"/>

<xsl:template match="/ns0:Messages/ns0:Message1/UpdateMultipleObjectsOperationsSchema/AccountContactRole/sObjects/">   
    <xsl:copy>
        <xsl:apply-templates select="sObject[generate-id(.) = generate-id( key ('trip-tth', concat(AccountId, '+', ContactId) ) )]"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="sObjects">
    <xsl:copy-of select="."/>
</xsl:template>

</xsl:stylesheet>

谢谢!

推荐答案

您走对了.您可以通过仅在 match 中指定元素名称而不是整个 XPath 来优化键声明.

You are on the right track. You can optimize the key declaration by specifying only the element name in the match instead of entire XPath.

<xsl:key name="group-key" match="sObject" use="concat(AccountId, '|', ContactId)" />

我们使用 identity template 将输入 XML 中的节点和属性按原样复制到输出,然后根据要求开始覆盖模板.

We use the identity template to copy the nodes and attributes from the input XML as is to output and then start overriding the templates as per the requirement.

<xsl:template match="node() | @*">
    <xsl:copy>
        <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
</xsl:template>

使用声明的键匹配.

<xsl:template match="sObject[generate-id() = generate-id(key('group-key', concat(AccountId, '|', ContactId))[1])]">
    <xsl:copy>
        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>

通过什么都不做"模板移除剩余的 元素.

Remove the remaining <sObject> elements by a "do nothing" template.

<xsl:template match="sObject" />

对于第二个要求,您可以保留第一个 <UpdateMultipleObjectsOperationsSchema/> 并使用以下模板删除其余部分.

For the 2nd requirement, you can retain the 1st <UpdateMultipleObjectsOperationsSchema/> and remove the rest by using the following templates.

<xsl:template match="ns0:Message2">
    <xsl:copy>
        <xsl:copy-of select="UpdateMultipleObjectsOperationsSchema[1]" />
    </xsl:copy>
</xsl:template>
<xsl:template match="ns0:Message2/UpdateMultipleObjectsOperationsSchema" />

整个XSLT如下

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*" />

    <xsl:key name="group-key" match="sObject" use="concat(AccountId, '|', ContactId)" />

    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="sObject[generate-id() = generate-id(key('group-key', concat(AccountId, '|', ContactId))[1])]">
        <xsl:copy>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="sObject" />

    <xsl:template match="ns0:Message2">
        <xsl:copy>
            <xsl:copy-of select="UpdateMultipleObjectsOperationsSchema[1]" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="ns0:Message2/UpdateMultipleObjectsOperationsSchema" />
</xsl:stylesheet>

输出

<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
    <ns0:Message1>
        <UpdateMultipleObjectsOperationsSchema>
            <AccountContactRole>
                <Operation>Create</Operation>
                <ObjectType>ACRObject</ObjectType>
                <TransactionLevel>REQUIRED</TransactionLevel>
                <sObjects>
                    <sObject>
                        <AccountId>A12345</AccountId>
                        <ContactId>C001</ContactId>
                        <Role>SalesPerson</Role>
                    </sObject>
                    <sObject>
                        <AccountId>A12345</AccountId>
                        <ContactId>C002</ContactId>
                        <Role>SalesPerson</Role>
                    </sObject>
                </sObjects>
            </AccountContactRole>
        </UpdateMultipleObjectsOperationsSchema>
    </ns0:Message1>
    <ns0:Message2>
        <UpdateMultipleObjectsOperationsSchema />
    </ns0:Message2>
</ns0:Messages>

这篇关于使用 XSLT 删除重复节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆