如何更改xml文件的结构格式?

时间:2018-07-14 10:56:24

标签: xml data-conversion

我有大量的xml文件,我想稍微改变一下它的格式。我怎样才能做到这一点?

这是我的问题:例如,我有以下内容:

<annotation>
<folder>New1</folder>
<filename>0000065.jpg</filename>
<path>C:\Users\farshad\Desktop\New1\0000065.jpg</path>
<source>
    <database>Unknown</database>
</source>
<size>
    <width>710</width>
    <height>287</height>
    <depth>3</depth>
</size>
<segmented>0</segmented>
<object>
    <name>car</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <difficult>0</difficult>
    <bndbox>
        <xmin>132</xmin>
        <ymin>47</ymin>
        <xmax>574</xmax>
        <ymax>283</ymax>
    </bndbox>
</object>
</annotation>

,我想将其更改为以下格式:

<annotation>
<folder>New1</folder>
<filename>0000065.jpg</filename>
<source>
<database>OXFORD-IIIT Pet Dataset</database>
<annotation>OXIIIT</annotation>
<image>flickr</image>
</source>
<size>
    <width>710</width>
    <height>287</height>
    <depth>3</depth>
</size>
<segmented>0</segmented>
<object>
    <name>car</name>
    <pose>Unspecified</pose>
    <truncated>0</truncated>
    <occluded>0</occluded>
    <bndbox>
        <xmin>132</xmin>
        <ymin>47</ymin>
        <xmax>574</xmax>
        <ymax>283</ymax>
    </bndbox>
    <difficult>0</difficult>
</object>
</annotation>

非常感谢您提出任何建议。

2 个答案:

答案 0 :(得分:0)

进行这种转换的通常方法是使用XSLT。我不会为您编写代码,并且建议您先阅读XSLT的基本概念,然后再进行概述:

定义用于处理注释元素的规则,该规则将使用相关规则处理其所有子元素:

<xsl:template match="annotation">
  <xsl:copy>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

定义用于处理注释子项的默认规则,即不变地复制它们:

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

定义删除<path>元素的规则:

<xsl:template match="path"/>

定义用于转换<source>元素的规则。我不知道您的逻辑是什么,所以我将其保留为未完成:

<xsl:template match="source">
   ...
</xsl:template>

有许多XSLT处理器可供选择。它们中的许多(包括Python的默认处理器)仅支持XSLT 1.0,对于这样的简单转换就足够了。稍后,您将遇到需要XSLT 2.0或3.0的更复杂的转换,因此您可能要从具有该功能的处理器开始。

答案 1 :(得分:0)

最后我找到了一些东西,对不起,这是因为我读了一些有关正则表达式的内容,该内容说我们不能将 RE 格式错误的语言一起使用>像XML或HTML一样,他们几乎不会说我们不能同时使用这两种功能,因此我决定使用 DOM 包或xml解析器包装来做到这一点,现在让我们开始:-

我为您创建了一个代码,您首先应该对其进行一些更改,然后再使用它,我很难建议您首先使用该程序并结合一些示例来学习如何首先使用它,我并不是说我的代码是无效的,但是您说的是大量文件,因此我不想误用所有文件,只需先对其进行测试以了解如何轻松使用它即可。

  

一些注意事项:-

1-TagIndex是标签名称的索引,有时有两个具有相同名称的元素,因此在您使用它时会使用它,它来自** *.getElementsByTagName(...)[tagIndex]。 / strong>

2-首先在一些示例中进行测试以学习使用它,您也不能这样做,但是由于一些小错误,我不想丢失所有数据,也不要害怕我不要说我的代码有错误,您可以自己阅读,但是此警告是由于数据丢失造成的。

3-不要忘记设置包含文件夹。

4-我想添加一个将来在某些指定元素之后或之前添加元素的方法,但是我没有这样做,因为我认为不需要这样做,尽管我创建了一个类来做到这一点你自己想要的。

5-在最后的for循环中的指定位置编写您的管理代码。

  

代码

import os, xml.dom.minidom as dom
from enum import Enum

#-----------------------definePath
containingFolder ="pathToContainingFolder"

files = os.listdir(containingFolder)

#if you want to add before and after specific elements
#then add this future to adding method
class addingPlace():

    class types(Enum):
        Parent = 0
        Above  = 1
        Below  = 2

    def __init__(self, TagName, PlaceType):
        self.TagName = TagName
        self.PlaceType = PlaceType

    def getElement(parser, tagIndex=0):
        return parser.getElementsByTagName(self.TagName)[tagIndex];


#---------------------delete element
def deleteElement(selfTag, parser, tagIndex=0):
    global s;
    try:
        s = parser.getElementsByTagName(selfTag)[tagIndex];
    except:
        print("Error in line 25 (tag name or tag index is invalid)")
        return;
    p = s.parentNode;
    try:
        p.removeChild(s);
    except:
        print("Error in line 27 (parent has no specified child)")


#---------------------add element
def addElement(tagName, parentTagName, parser, elementText=None, parentTagIndex=0):
    element = dom.Element(tagName)

    if(elementText is not None):
        txt = dom.Text()
        txt.data = elementText
        element.childNodes.append(txt)

    try:
        parentElement = parser.getElementsByTagName(parentTagName)[parentTagIndex]
        parentElement.childNodes.append(element)
    except:
        print("Error in line 41 (parent tag name or tag index is invalid)")


#-------------------tranfer element to specified parent
def transferElement(tagName, parentTagName, parser, tagIndex=0, parentTagIndex=0):
    try:
        deleting = parser.getElementsByTagName(tagName)[tagIndex];
    except:
        print("Error in line 47 (tag name or tag index is invalid)")
        return;
    element = deleting.cloneNode(True)
    deleting.parentNode.removeChild(deleting)
    try:
        parentElement = parser.getElementsByTagName(parentTagName)[parentTagIndex]
    except:
        print("Error in line 53 (parent tag name or tag index is invalid)")
    parentElement.childNodes.append(element)



#----------------------usage location

for f in files:
    with open(os.path.join(containingFolder, f), 'r+') as fl:
        fileText = fl.read()
        xmlParsed = dom.parseString(fileText)     #use this as parser
        root = xmlParsed.documentElement.nodeName #use this as root element        

        #there you can use adding and deleting and trans.. methods
        # this is an example:-
        #addElement("C_Type",root,xmlParsed,elementText="ASCI")


        formattedText = xmlParsed.toxml()
        fl.seek(0);
        fl.write(formattedText);
        fl.truncate();