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

如何更改xml文件的结构格式?,xml,data-conversion,Xml,Data Conversion,我有一大组xml文件,我想稍微改变一下它的格式。我该怎么做 这是我的问题:例如,我有以下几点: <annotation> <folder>New1</folder> <filename>0000065.jpg</filename> <path>C:\Users\farshad\Desktop\New1\0000065.jpg</path> <source> <database>Un

我有一大组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>

新1
0000065.jpg
C:\Users\farshad\Desktop\New1\0000065.jpg
不为人知
710
287
3.
0
汽车
未指明
0
0
132
47
574
283
我想将其更改为以下格式:

<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>

新1
0000065.jpg
牛津-IIIT宠物数据集
肟
相片分享
710
287
3.
0
汽车
未指明
0
0
132
47
574
283
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>

定义删除
元素的规则:

<xsl:template match="path"/>

定义转换
元素的规则。我不知道你的逻辑是什么,所以我不想让它完成:

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

...

有多种XSLT处理器可供选择。其中许多(包括Python的默认处理器)只支持XSLT1.0,这对于这样的简单转换来说已经足够了。稍后您将遇到需要XSLT 2.0或3.0的更复杂的转换,因此,您可能希望从具有该功能的处理器开始。

最后,我发现了一些东西,我很抱歉,因为我读到了一些关于正则表达式的内容,其中说我们不能将RE恶意语言(如XML或HTML)一起使用,他们几乎没有说我们不能同时使用这两个东西,所以我决定使用DOM包或xml解析器包来实现这一点,现在让我们开始:-

我为您创建了一个代码,您应该首先对其进行一些更改,然后再使用它,我几乎不建议您首先使用这个程序,通过一些示例来学习如何首先使用它,我不是说我的代码无效,但您说它有大量的文件,所以我不想错误地使用它们,只需先测试它,学习如何轻松使用它

一些注意事项:-

1-
TagIndex
es是标记名的索引,有时有两个元素具有相同的名称,因此在发生时使用它,它来自**
*。getElementsByTagName(…)[TagIndex]

2-首先在一些示例上测试它,学习如何使用它,您也可以不这样做,但我不想因为一些小错误而丢失所有数据,也不要害怕我不会说我的代码有错误,您可以自己阅读,但此警告是因为丢失了数据。

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

4-我想在某些指定元素之后或之前添加一个未来元素,但我没有这样做,因为我认为没有必要这样做,尽管我创建了一个类,如果您愿意的话可以这样做。

5-在指定位置的最终for循环中写入管理代码。

代码


您使用哪种语言?根据您可用的技能和工具,有太多的选项(例如XSLT,任何通用语言都有XML解析器/编写器)。我们可以帮助您了解使用工具的详细信息,但不提供工具建议。您应该使用您熟悉的语言创建一个程序,然后自己编写。这次当您编写一些代码时,如果您有错误,我们可以帮助您。我使用python。python中有这样的工具吗?是的,最好是自己动手,我们可以在您出现错误时帮助您
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();