2012-01-24 29 views
30

Tôi đang cố gắng phát triển mã Python đơn giản (3.2) để đọc các tệp XML, thực hiện một số chỉnh sửa và lưu trữ chúng trở lại. Tuy nhiên, trong bước lưu trữ, ElementTree bổ sung thêm danh pháp vùng tên. Ví dụ:Lưu tệp XML bằng ElementTree

<ns0:trk> 
    <ns0:name>ACTIVE LOG</ns0:name> 
<ns0:trkseg> 
<ns0:trkpt lat="38.5" lon="-120.2"> 
    <ns0:ele>6.385864</ns0:ele> 
    <ns0:time>2011-12-10T17:46:30Z</ns0:time> 
</ns0:trkpt> 
<ns0:trkpt lat="40.7" lon="-120.95"> 
    <ns0:ele>5.905273</ns0:ele> 
    <ns0:time>2011-12-10T17:46:51Z</ns0:time> 
</ns0:trkpt> 
<ns0:trkpt lat="43.252" lon="-126.453"> 
    <ns0:ele>7.347168</ns0:ele> 
    <ns0:time>2011-12-10T17:52:28Z</ns0:time> 
</ns0:trkpt> 
</ns0:trkseg> 
</ns0:trk> 

Đoạn mã dưới:

def parse_gpx_data(gpxdata, tzname=None, npoints=None, filter_window=None, 
        output_file_name=None): 
     ET = load_xml_library(); 

    def find_trksegs_or_route(etree, ns): 
     trksegs=etree.findall('.//'+ns+'trkseg') 
     if trksegs: 
      return trksegs, "trkpt" 
     else: # try to display route if track is missing 
      rte=etree.findall('.//'+ns+'rte') 
      return rte, "rtept" 

    # try GPX10 namespace first 
    try: 
     element = ET.XML(gpxdata) 
    except ET.ParseError as v: 
     row, column = v.position 
     print ("error on row %d, column %d:%d" % row, column, v) 

    print ("%s" % ET.tostring(element)) 
    trksegs,pttag=find_trksegs_or_route(element, GPX10) 
    NS=GPX10 
    if not trksegs: # try GPX11 namespace otherwise 
     trksegs,pttag=find_trksegs_or_route(element, GPX11) 
     NS=GPX11 
    if not trksegs: # try without any namespace 
     trksegs,pttag=find_trksegs_or_route(element, "") 
     NS="" 

    # Store the results if requested 
    if output_file_name: 
     ET.register_namespace('', GPX11) 
     ET.register_namespace('', GPX10) 
     ET.ElementTree(element).write(output_file_name, xml_declaration=True) 

    return; 

Tôi đã thử bằng cách sử dụng register_namespace, nhưng không có kết quả dương tính. Có bất kỳ thay đổi cụ thể nào cho phiên bản ElementTree 1.3 này không?

+0

Nói cho tôi biết nếu tôi hiểu bạn câu hỏi, bạn muốn có '' thay vì ' 'và như vậy? –

+0

Chính xác. Tôi muốn có thay vì và v.v. – ilya1725

+0

Đây không phải là một giải pháp thực sự nhưng vì có vẻ như bạn tải một chuỗi, bạn đã cố gắng để loại bỏ không gian tên với một số regexp? Sau đó, nếu bạn tải và lưu mà không có mọi thứ sẽ ổn. –

Trả lời

55

Để tránh tiền tố ns0, không gian tên mặc định phải được đặt trước khi đọc dữ liệu XML.

ET.register_namespace('', "http://www.topografix.com/GPX/1/1") 
ET.register_namespace('', "http://www.topografix.com/GPX/1/0") 
+0

Có vẻ như không phải trước đây. Tôi có thể đọc tập tin XML và nhận được không gian tên và chỉ sau khi thiết lập register_namespace đó. cây = ET.parse (str (udx_path)) root = tree.getroot() ns = { # chiết xuất namespace của phần tử gốc 'UDX': root.tag [1: root.tag.index (' } ')] } ET.register_namespace (' ', root.tag [1: root.tag.index ('} ')]) – likern

0

Có vẻ như bạn phải khai báo không gian tên của bạn, có nghĩa là bạn cần thay đổi dòng đầu tiên của xml của bạn từ:

<ns0:trk> 

một cái gì đó như:

<ns0:trk xmlns:ns0="uri:"> 

Khi đã làm điều đó bạn sẽ không còn nhận được ParseError: for unbound prefix: ... và:

elem.tag = elem.tag[(len('{uri:}'):] 

sẽ xóa tên át chủ.

+0

Xin chào Rik. Ví dụ XML tôi đã hiển thị là _output_. XML đầu vào, phân tích cú pháp tốt, không có tiền tố 'ns0:'. Nó chỉ là mã GPX chuẩn. – ilya1725

+0

Nếu dòng 'phần tử = ET.XML (gpxdata)' cung cấp cho bạn một phần tử có 'ns0' thì" vấn đề "nằm trong gpxdata, trong trường hợp này bạn phải có tùy chọn:" sửa "gpxdata hoặc tìm hiểu tại sao tiêu chuẩn trình phân tích cú pháp thực hiện điều đó và tạo một cái mới cho ['ET.XML'] (http://docs.python.org/py3k/library/xml.etree.elementtree.html#xml.etree.ElementTree.XML). –

+0

Gpxdata gốc không có bất kỳ mục nhập 'ns0' nào. Tuy nhiên, gợi ý của bạn, Rik, loại dẫn tôi đến giải pháp. Về cơ bản, cần có 'ET.register_namespace ('', GPX11)' 'ET.register_namespace ('', GPX10)' trước khi đọc, tức là 'ET.XML'. – ilya1725

1

Câu trả lời này thực sự đã giúp tôi tránh vấn đề ns0. Tôi đang chuyển đổi GPX từ GPaws (khi nó hoạt động) thành KML (cho Google maps) và mã của tôi không hoạt động cho đến khi tôi đặt không gian tên mặc định như thế này ET.register_namespace(""," http://www.opengis.net/kml/2.2 ")

6

Bạn cần đăng ký tất cả không gian tên của mình.

Ví dụ: Nếu bạn có xml đầu vào của bạn như thế này

<Capabilities xmlns="http://www.opengis.net/wmts/1.0" 
    xmlns:ows="http://www.opengis.net/ows/1.1" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:gml="http://www.opengis.net/gml" 
    xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" 
    version="1.0.0"> 

Sau đó, bạn phải đăng ký tất cả các không gian tên tức là thuộc tính hiện tại với xmlns như thế này:

ET.register_namespace('', "http://www.opengis.net/wmts/1.0") 
ET.register_namespace('ows', "http://www.opengis.net/ows/1.1") 
ET.register_namespace('xlink', "http://www.w3.org/1999/xlink") 
ET.register_namespace('xsi', "http://www.w3.org/2001/XMLSchema-instance") 
ET.register_namespace('gml', "http://www.opengis.net/gml") 
Các vấn đề liên quan