Слияние файлов XML с одинаковыми узлами с использованием Python - PullRequest
0 голосов
/ 11 октября 2018

Хотите объединить следующий 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 не дали никаких подсказок, и что вопрос заключался в том, чтобы получить предложения о том, с чего начать..

1 Ответ

0 голосов
/ 11 октября 2018

Поскольку вы готовы рассмотреть альтернативы кодированию на 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 говорит о том, как обрабатывать каждую группу элементов, совместно использующих ключ слияния;в этом случае мы выводим отдельные элементы <members>, используя xsl:for-each-group, затем выводим <name>.

Существует одно различие между выводом и желаемым выводом: таблица стилей производит вывод, отсортированный по <name>.Я не уверен, каковы были ваши критерии сортировки результатов;если порядок вывода важен, нам могут потребоваться корректировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...