漂亮的打印子节点没有命名空间声明

时间:2017-09-26 22:19:10

标签: python xml python-2.7 lxml

我有一个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非常好的原因。

1 个答案:

答案 0 :(得分:0)

您可以使用Python正则表达式模块(re)。有一个function for substitution。所以你可以用空字符串替换命名空间。

import re

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