【问题标题】:Take 2 XML elements and merge into 1 new element - Python取 2 个 XML 元素并合并为 1 个新元素 - Python
【发布时间】:2018-06-23 06:52:26
【问题描述】:

我目前正在开发一个使用 OpenStreetMap XML 文档的项目。该项目的一部分是验证一些数据及其一致性。我对 Python 和使用 XML 文件还很陌生,所以我真的不知道从哪里开始。

这是我的 XML 文档的 sn-p:

  <way id="11005330" version="2" timestamp="2013-02-05T20:56:45Z" changeset="14926577" uid="451693" user="bot-mode">
<nd ref="98006629"/>
<nd ref="98006630"/>
<nd ref="98006631"/>
<tag k="highway" v="residential"/>
<tag k="name" v="Kiwi Court"/>
<tag k="tiger:cfcc" v="A41"/>
<tag k="tiger:county" v="Lake, FL"/>
<tag k="tiger:name_base" v="Kiwi"/>
<tag k="tiger:name_type" v="Ct"/>
<tag k="tiger:reviewed" v="no"/>
<tag k="tiger:zip_left" v="34714"/>
<tag k="tiger:zip_right" v="34714"/>

我现在想做的是:

    <tag k="tiger:name_base" v="Kiwi"/>
    <tag k="tiger:name_type" v="Ct"/>

并将它们组合成一个新标签:

<tag k="addr:street" v="Kiwi Ct"/>

另一件事是,并非所有这些都同时具有 name_base 和 name_type。所以对于那些我只想创建 addr:street 标签的人。

这是一个非常大的文件,因此必须逐个查看并创建它。创建新标签后,我需要继续删除元素。

我正在使用:import xml.etree.cElementTree as ET

编辑

我能够解决部分问题

    root = tree.getroot()
    for way in root.findall(".//way"):
        kbool = False
        tbool = False
        for key in way.iterfind(".//tag"):
            if key.attrib['k'] == "tiger:name_base":
                kbool = True
                # print(key.attrib['v'])
                base = key.attrib['v']
            if key.attrib['k'] == "tiger:name_type":
                tbool = True
                ttype = key.attrib['v']
        if kbool == True and tbool == True:
            ET.SubElement(way, 'tag k="addr:street" v="{} {}"'.format(base, ttype))
        elif kbool == True and tbool == False:
            ET.SubElement(way, 'tag k="addr:street" v="{}"'.format(base))


tree.write('maps')

我现在遇到的问题是它正在编写地址属性,即使是没有tiger:name_base 键的方式。

【问题讨论】:

    标签: python xml celementtree


    【解决方案1】:

    使用ElementTree

    XML = """<root>
        <way id="11005330" version="2" timestamp="2013-02-05T20:56:45Z" changeset="14926577" uid="451693" user="bot-mode">
            <nd ref="98006629"/>
            <nd ref="98006630"/>
            <nd ref="98006631"/>
            <tag k="highway" v="residential"/>
            <tag k="name" v="Kiwi Court"/>
            <tag k="tiger:cfcc" v="A41"/>
            <tag k="tiger:county" v="Lake, FL"/>
            <tag k="tiger:name_base" v="Kiwi"/>
            <tag k="tiger:name_type" v="Ct"/>
            <tag k="tiger:reviewed" v="no"/>
            <tag k="tiger:zip_left" v="34714"/>
            <tag k="tiger:zip_right" v="34714"/>
        </way>
    </root>"""
    

    演示:

    import xml.etree.ElementTree as ET
    
    tree = ET.parse(filename)
    doc = tree.getroot()
    for way in doc.findall(".//way"):            #Find all way tags
        name_base = way.find('.//tag[@k="tiger:name_base"]').get("v")     #Get tiger:name_base attr
        way.remove(way.find('.//tag[@k="tiger:name_base"]'))              #Remove Tag
        name_type = way.find('.//tag[@k="tiger:name_type"]').get("v")     #Get tiger:name_type attr
        way.remove(way.find('.//tag[@k="tiger:name_type"]'))              #Remove Tag
        newNode = ET.SubElement(way, '''tag k="addr:street" v="{} {}"'''.format(name_base, name_type))    #Add New Tag
    tree.write(r"C:\Users\Rakesh\Desktop\testFiles\A2.xml")               #Write to file
    

    输出:

    <root>
        <way changeset="14926577" id="11005330" timestamp="2013-02-05T20:56:45Z" uid="451693" user="bot-mode" version="2">
            <nd ref="98006629" />
            <nd ref="98006630" />
            <nd ref="98006631" />
            <tag k="highway" v="residential" />
            <tag k="name" v="Kiwi Court" />
            <tag k="tiger:cfcc" v="A41" />
            <tag k="tiger:county" v="Lake, FL" />
            <tag k="tiger:reviewed" v="no" />
            <tag k="tiger:zip_left" v="34714" />
            <tag k="tiger:zip_right" v="34714" />
        <tag k="addr:street" v="Kiwi Ct" /></way>
    </root>
    

    【讨论】:

    • 这对我不起作用 :( 我收到一个属性错误 AttributeError: 'NoneType' object has no attribute 'get' 这是 for 循环内的第一条语句
    • 试试if way.find('.//tag[@k="tiger:name_base"]'): name_base = way.find('.//tag[@k="tiger:name_base"]').get("v")
    • 这样就修复了错误,但它没有写入值或删除旧值,对于新标签,它正在为所有内容写入 v= " "。也许是我的文件,我更新了我的 xml 文档的格式。
    • 我编辑了我的帖子,我能够让它工作,但现在遇到了另一个问题。有什么想法吗?
    • 抱歉要标记你@Rakesh
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多