2014-11-26 1 views
4

У меня есть два файла XML, которые я пытаюсь объединить.Объединяйте XML-файлы везде, где идентификатор атрибута один и тот же Python

XML1:

<hierachyAttributes> 
    <attribute> 
     <displayOrder>2</displayOrder> 
     <attributeID>Demographics</attributeID> 
     <children> 
      <attribute> 
       <displayOrder>1</displayOrder> 
       <attributeID>age</attributeID> 
     </children> 
    </attribute> 
</hierachyAttributes> 

xml2:

<diseaseAttributes> 
    <diseaseName>Cancer</diseaseName> 
    <diseaseID>1322843</diseaseID> 
    <metaAttributes> 
     <attribute> 
      <description>Age</description> 
      <displayName>Age (years)</displayName> 
      <attributeID>age</attributeID> 
      <type>Double</type> 
      <attributeCategory>Clinical</attributeCategory> 
      <displayInSummary>TRUE</displayInSummary> 
       <group> 
        <displayOrder>1</displayOrder> 
        <displayName>0 - &lt; 10</displayName> 
        <minValue>0</minValue> 
        <minInclusive>TRUE</minInclusive> 
        <maxValue>10</maxValue> 
        <maxInclusive>FALSE</maxInclusive> 
       </group> 
      </valueGroups> 
     </attribute> 
    </metaAttributes> 
</diseaseAttributes> 

Есть ли способ, чтобы объединить их, как показано ниже, даже с разными корневыми тегов, в данном случае hierachyAttributes и diseaseAttributes? CombinedXML:

<hierachyAttributes> 
<diseaseAttributes> 
    <diseaseName>Cancer</diseaseName> 
    <diseaseID>1322843</diseaseID> 
    <metaAttributes> 
     <attribute> 
     <displayOrder>2</displayOrder> 
     <attributeID>Demographics</attributeID> 
     <children> 
      <attribute> 
       <displayOrder>1</displayOrder> 
       <attributeID>age</attributeID> 
       <description>Age</description> 
       <displayName>Age (years)</displayName> 
       <type>Double</type> 
       <attributeCategory>Clinical</attributeCategory> 
       <displayInSummary>TRUE</displayInSummary> 
        <group> 
         <displayOrder>1</displayOrder> 
         <displayName>0 - &lt; 10</displayName> 
         <minValue>0</minValue> 
         <minInclusive>TRUE</minInclusive> 
         <maxValue>10</maxValue> 
         <maxInclusive>FALSE</maxInclusive> 
        </group> 
       </valueGroups> 
      </attribute> 
     </children> 
    </metaAttributes> 
</diseaseAttributes> 
</hierachyAttributes> 

т.е. объединить их везде, где attributeID такое же. Я попробовал следующее, но он объединил один файл xml за другим.

#!/usr/bin/env python 
import sys 
from xml.etree import ElementTree 

def run(files): 
    first = None 
    for filename in files: 
     data = ElementTree.parse(filename).getroot() 
     if first is None: 
      first = data 
     else: 
      first.extend(data) 
    if first is not None: 
     print ElementTree.tostring(first) 

if __name__ == "__main__": 
    run(sys.argv[1:])   

Или, если тег заменяется, и я хочу такой же вывод, но под одним корневым узлом, т.е. diseaseAttributes, как можно достичь этого?

ответ

3

В вашем первом файле XML отсутствует закрывающий </attribute> тег под <children>. Они также просто ужасны с точки зрения структуры - смехотворно многословно и смутно названы так, что я действительно не думаю, что могу сказать, что вы пытаетесь сделать.

Первый файл выглядит так, как будто он просто выражает дерево отношений «атрибутов». Это второе, что я не получаю - он, по-видимому, содержит определение атрибута «Возраст» с именем, какой тип данных он есть, но он является частью под «Раком». Зачем? Я предполагаю, что вы собираетесь отображать результаты, разбитые по возрасту, но почему Возраст привязан к Раку? Что произойдет, если у вас есть данные о возрасте, например. зимние смерти от гриппа, имеет ли он свой собственный уникальный атрибут Age?

На самом деле, мой первый вопрос ... будет ли это как xml2 должно работать:

<disease-definitions> 
    <disease-definition id="1322843"> 
    <name>Cancer</name> 

    <attribute-definitions> 
     <attribute id="age" category="Clinical"> 
     <description>Age</description> 
     <displayName>Age (years)</name> 
     <type>Double</type> 

     <attribute-summary displayed="true"> 
      <group> 
      <displayName>&lt; 10</displayName> 
      <range type="half-open"> 
       <min>0</min> 
       <max>10</max> 
      </range> 
      </group> 
      <group> 
      <displayName>10 - 20</displayName> 
      <range type="half-open"> 
       <min>10</min> 
       <max>20</max> 
      </range> 
      </group> 
     </attribute-summary> 
     </attribute> 
    </attribute-definitions> 
    </disease-definition> 

    <disease-definition id="1322844"> 
    <name>Influenza</name> 

    <attribute-definitions> 
     <attribute id="age" category="Clinical"> 
     <description>Age</description> 
     <displayName>Age (years)</name> 
     <type>Double</type> 

     <attribute-summary displayed="true"> 
      <group> 
      <displayName>Children</displayName> 
      <range type="half-open"> 
       <min>0</min> 
       <max>18</max> 
      </range> 
      </group> 
      <group> 
      <displayName>Adults</displayName> 
      <range type="half-open"> 
       <min>18</min> 
       <max>60</max> 
      </range> 
      </group> 
      <group> 
      <displayName>Elderly</displayName> 
      <range type="half-open"> 
       <min>60</min> 
      </range> 
      </group> 
     </attribute-summary> 
     </attribute> 
    </attribute-definitions> 
    </disease-definition> 
<disease-definitions> 

Потому что, кажется, что вы намекаете, так ужасно, как это даже тогда, когда я это делаю немного меньше. И я не уверен, как иерархическая информация вписывается в нее.

Есть ли атрибуты и их иерархия только для отображения данных? Даже тогда, это, кажется, лучше

<attribute id="demographics"> 
    <title>Demographics</title> 
    <children> 
    <child id="age" /> 
    <child id="gender" /> 
    </children> 
</attribute> 

<attribute id="epidemiology"> 
    <title>Epidemiology</title> 
    <children> 
    <child id="reported-date" /> 
    <child id="variant-strains" /> 
    </children> 
</attribute> 

<attribute id="age"> 
    <title>Age</title> 
    <description>Age in years</description> 
    <category>Clinical</category> 

    <data type="double"> 
    <min-value>0</min-value> 
    </data> 
</attribute> 

<attribute id="gender"> 
    <title>Gender</title> 

    <data type="options"> 
    <one-of> 
     <option id="M"> 
     <title>Male</title> 
     </option> 
     <option id="F"> 
     <title>Female</title> 
     </option> 
    </one-pf> 
    </data> 
</attribute> 

, а затем

<disease-definitions> 
    <disease id="1322843"> 
    <displayName>Cancer</displayName> 

    <disease-attributes> 
     <attribute ref-id="age"> 
     <displayName>Age of death</displayName> 

     <displayed-in-summary>true</displayed-in-summary> 
     <display format="histogram"> 
      <range max="10">Up to 10</range> 
      <range min="10" max="25">Teenagers &amp; young adults</range> 
      <range min="25" max="55">Adults</range> 
      <range min="55">Elderly</range> 
     </display-data> 
     <display 
     </attribute> 

     <attribute ref-id="gender"> 
     <displayName>Gender of death</displayName> 

     <displayed-in-summary>true</displayed-in-summary> 
     <display format="pie"> 
      <slice option-id="M" background="#44F">Male deaths</slice> 
      <slice option-id="F" background="#F44">Female deaths</slice> 
     </display-data> 
     <display 
     </attribute> 
    </disease-attributes> 
    </disease> 

    <disease id="1322844"> 
    <displayName>Influenza</displayName> 

    <disease-attributes> 
     <attribute ref-id="age"> 
     <displayName>Age of death</displayName> 

     <displayed-in-summary>true</displayed-in-summary> 
     <display-data format="grouped"> 
      <range max="10">Up to 10</range> 
      <range min="10" max="25">Teenagers &amp; young adults</range> 
      <range min="25" max="55">Adults</range> 
      <range min="55">Elderly</range> 
     </display-data> 
     <display 
     </attribute> 
    </disease-attributes> 
    </disease> 

</disease-definitions> 
+0

Я просто разместил части файлов XML. Поэтому, пожалуйста, игнорируйте любые несоответствующие теги. В конечном счете, я хотел бы объединить два файла, когда атрибуты одинаковы, я не хочу указывать его на «возраст» или «рак» в целом. Я бы хотел, чтобы он работал для каждого атрибута и root. – abn

+0

Объединить как? Единственное, что у них обоих есть: 1 ', где-то в обоих, но вы даже не сказали, какой XML-документ является тем, с кем вы сливаетесь, и который он собирается, но только оба корневых элемента на выходе просто для того, чтобы сделать его ошибочным и более запутанным. Этот процесс не является - ваш «вывод» должен как-то сделать его более запутанным. – spiralx

0

Я думаю, что вы хотите сделать, это лучше всего сделать, установив модуль lxml с помощью

pip install lxml

и использовать его для любого кода, связанного с XML, так как он гораздо лучше используется, чем встроенный материал. Взгляните на учебник, есть много способов сделать что-то, где вы загружаете, разбираете и обрабатываете атрибуты атрибутов в каждом файле в одном процессе.

Там больше полезной информации на

Python XML processing with lxml