【问题标题】:How can I change the structure format of an xml file?如何更改 xml 文件的结构格式?
【发布时间】:2018-12-22 13:58:21
【问题描述】:

我有大量的 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>

非常感谢您的任何建议。

【问题讨论】:

  • 您使用哪种语言?
  • 选项太多,具体取决于您可用的技能和工具(例如 XSLT,任何通用语言都有 XML 解析器/编写器)。我们可以帮助您了解使用工具的详细信息,但Stack Overflow 不做工具推荐。
  • 您应该使用您知道的语言创建一个程序并自己动手,这一次当您编写一些代码时,如果您有错误,我们可以帮助您。
  • 我使用python。 python中有这样的工具吗?
  • 是的,最好自己做,当您遇到错误时我们可以帮助您

标签: xml data-conversion


【解决方案1】:

我终于找到了一些东西,我很抱歉,因为我读到了一些关于 Regular Expressions 的内容,其中说我们不能将 REMaliformed Languages 一起使用> 就像 XML 或 HTML 一样,他们几乎没有说我们不能同时使用这两个东西,所以我决定使用 DOM 包或 xml 解析器包来实现,所以现在让我们开始吧:-

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

一些注意事项:-

1 - TagIndexes 是标签名称的索引,有时有两个相同名称的元素,所以当你遇到它时使用它,它来自** *.getElementsByTagName(...)[tagIndex]

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();

【讨论】:

    【解决方案2】:

    这种转换的常用方法是使用 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>
    

    定义删除&lt;path&gt;元素的规则:

    <xsl:template match="path"/>
    

    定义转换&lt;source&gt; 元素的规则。我不知道你的逻辑是什么,所以我会留下未完成的:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-27
      • 1970-01-01
      • 2010-11-22
      • 2014-01-11
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多