繁体   English   中英

使用python合并具有相同节点的XML文件

[英]Merging XML files with identical nodes using python

希望合并以下XML。 我想在Python中做到这一点,尽管无论如何都不是必需的。

文件1:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types> 
        <members>Class 1</members> 
        <members>Class 2</members>    
        <name>ApexClass</name>
    </types>
    <types>
        <members>Trigger 1</members>
        <name>ApexTrigger</name>
    </types>
    <types>
        <members>Rule 1</members>
        <members>Rule 2</members>
        <name>WorkflowRule</name>
    </types>   
    <types>
        <members>Address</members>
        <name>CustomField</name>
    </types>     
    <version>39.0</version>
</Package>

档案2:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Class 3</members>  
        <name>ApexClass</name>
    </types>
    <types>
        <members>Rule 2</members>
        <name>WorkflowRule</name>
    </types>  
    <types>
        <members>Phone</members>
        <name>CustomField</name>
    </types>     
    <version>41.0</version>
</Package>

合并文件1文件2以在下面创建文件3

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>Class 1</members> 
        <members>Class 2</members>    
        <members>Class 3</members>    
        <name>ApexClass</name>
    </types>
    <types>
        <members>Trigger 1</members>
        <name>ApexTrigger</name>
    </types>
    <types>
        <members>Rule 1</members>
        <members>Rule 2</members>
        <name>WorkflowRule</name>
    </types>  
    <types>
        <members>Address</members>
        <members>Phone</members>
        <name>CustomField</name>
    </types>     
    <version>41.0</version>
</Package>

请注意,识别节点可以是50多个不同值之一。

在此先感谢您的协助。

编辑:哎呀,投反对票很痛。 为了澄清和证明这个问题,我应该指出,由于对SO的广泛搜索没有任何线索,因此我很难确定从哪里开始这个问题,并且问题的重点是从何处开始获得建议。

由于您已准备好考虑使用Python编码的替代方法,因此这里提供了XSLT 3.0解决方案:

<xsl:transform version="3.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    xpath-default-namespace="http://soap.sforce.com/2006/04/metadata"
    expand-text="true">
    <xsl:param name="file1" as="xs:string"/>
    <xsl:param name="file2" as="xs:string"/>
    <xsl:template name="xsl:initial-template">
        <Package xmlns="http://soap.sforce.com/2006/04/metadata">
            <xsl:merge>
                <xsl:merge-source for-each-source="$file1, $file2"
                    select="//types" sort-before-merge="true">
                    <xsl:merge-key select="name"/>
                </xsl:merge-source>
                <xsl:merge-action>
                    <types>
                        <xsl:for-each-group select="current-merge-group()/members"
                            group-by=".">
                            <xsl:copy-of select="current-group()[1]"/>
                        </xsl:for-each-group>
                        <name>{current-merge-key()}</name>
                    </types>
                </xsl:merge-action>
            </xsl:merge>
        </Package>
    </xsl:template>
</xsl:transform>

您可以从命令行运行此命令,如下所示:

java net.sf.saxon.Transform -xsl:test.xsl -t -it file1=file1.xml file2=file2.xml !indent=yes

说明: xsl:merge-source标识要合并的元素的两个序列; xsl:merge-key定义了要在其上进行合并的键,并告诉我们该序列尚未按该键排序。 xsl:merge-action表示如何处理共享键的每组元素; 在这种情况下,我们使用xsl:for-each-group输出不同的<members>元素,然后输出<name>

输出与所需输出之间有一个区别:样式表生成按<name>排序的输出。 我不确定您对输出进行排序的标准; 如果输出顺序很重要,那么我们可能需要进行调整。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM