2017-09-26 27 views
0

我有一個XML文檔,我想提取一個子節點(boundedBy)和pretty_print完全像它在原始文檔中看起來(除了漂亮的格式)。沒有命名空間聲明的漂亮的打印子節點

<?xml version="1.0" encoding="UTF-8" ?> 
<wfs:FeatureCollection 
    xmlns:sei="https://somedomain.com/namespace" 
    xmlns:wfs="http://www.opengis.net/wfs" 
    xmlns:gml="http://www.opengis.net/gml" 
    xmlns:ogc="http://www.opengis.net/ogc" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd 
         https://somedomain.com/schemas/wfsnamespace some.xsd"> 
     <gml:boundedBy> 
     <gml:Box srsName="EPSG:4326"> 
      <gml:coordinates>-10.934396,-139.997120 77.396455,-53.627763</gml:coordinates> 
     </gml:Box> 
     </gml:boundedBy> 
    <gml:featureMember> 
     <sei:HUB_HEIGHT_FCST> 
     <!--- This is the section I want ---> 
     <gml:boundedBy> 
      <gml:Box srsName="EPSG:4326"> 
       <gml:coordinates>14.574435,-139.997120 14.574435,-139.997120</gml:coordinates> 
      </gml:Box> 
     </gml:boundedBy> 
     <!--- This is the section I want ---> 
     <sei:geometry_4326> 
     <gml:Point srsName="EPSG:4326"> 
      <gml:coordinates>14.574435,-139.997120</gml:coordinates> 
     </gml:Point> 
     </sei:geometry_4326> 
     <sei:rundatetime>2017-09-26 00:00:00</sei:rundatetime> 
     <sei:validdatetime>2017-09-26 17:00:00</sei:validdatetime> 
     </sei:HUB_HEIGHT_FCST> 
    </gml:featureMember> 
</wfs:FeatureCollection> 

這裏是我如何提取的子節點:

# parse the xml string 
parser = etree.XMLParser(remove_blank_text=True, remove_comments=True, recover=False, strip_cdata=False) 
root = etree.fromstring(xmlstr, parser=parser) 
#find the subnode I want 
subnodes = root.xpath("./gml:boundedBy", namespaces={'gml': 'http://www.opengis.net/gml'}) 
subnode = subnodes[0] 
# make a pretty output 
xmlstr = etree.tostring(subnode, xml_declaration=False, encoding="UTF-8", pretty_print=True) 
print xmlstr 

這給了我這個。不幸的是,lxml正在將命名空間添加到boundedBy節點(爲了xml的完整性,這是有意義的)。

<gml:boundedBy xmlns:gml="http://www.opengis.net/gml" xmlns:sei="https://somedomain.com/namespace" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <gml:Box srsName="EPSG:4326"> 
    <gml:coordinates>-10.934396,-139.997120 77.396455,-53.627763</gml:coordinates> 
    </gml:Box> 
</gml:boundedBy> 

我只希望子節點,因爲它在原始文檔中看去。

<gml:boundedBy> 
    <gml:Box srsName="EPSG:4326"> 
     <gml:coordinates>14.574435,-139.997120 14.574435,-139.997120</gml:coordinates> 
    </gml:Box> 
</gml:boundedBy> 

我有沒有使用lxml的靈活,但無論哪種方式,我還沒有找到如何做到這一點的選擇。


編輯: 由於有人指出,我應該解釋爲什麼我要做到這一點...

我試圖登錄的XML片段,而不會改變它的原始結構。我正在構建的自動化測試查看某些節點的正確性。在這個過程中,我正在記錄這個片段,並希望讓它更容易閱讀。一些片段可能會變得相當大,這就是爲什麼pretty_print非常好。

+2

您正在要求圖書館幫助您創建「XML」,它不是* [** namespace-well-formed **](https://stackoverflow.com/a/25830482/290085) 。這不會幫助你做到這一點,你不應該試圖做到這一點。 – kjhughes

+0

...但如果你只是真的希望未包含* unused *名稱空間聲明,那麼你的請求會更合理。他們在那裏沒有錯 - 只是不必要的,可以說是難看。 – kjhughes

+0

我很清楚,lxml添加它們並沒有錯。這不是我問的問題。我想打印原始文檔的一個片段。這個的目的不在於有效的xml,而是關於打印xml的部分。 –

回答

0

您可以使用Python正則表達式模塊(re)。有一個function for substitution。所以你可以用一個空字符串替換命名空間。

import re 

print re.sub(' xmlns:\w+="[^"]+"', '', xmlstr) 
+1

我想過這樣做。它感覺有點髒。 –