【发布时间】:2017-09-26 22:19:10
【问题描述】:
我有一个 xml 文档,我想提取一个子节点 (boundedBy) 并按照原始文档中的样子进行漂亮打印(漂亮格式除外)。
<?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 如此出色的原因。
【问题讨论】:
-
您要求库帮助您创建 不是 namespace-well-formed 的“XML”。它不会帮助你做到这一点,你不应该尝试这样做。
-
...但如果您只是真的希望不包含 unused 命名空间声明,那么您的请求会更合理。他们的存在并没有错——只是不必要的,而且可以说是难看的。
-
我很清楚 lxml 添加它们并没有错。这不是我要问的问题。我想打印原始文档的片段。这样做的全部目的不是关于有效的 xml,而是关于打印 xml 的部分。
-
然后编写自己的序列化程序。也许你可以破解 lxml 中的那个来满足你的需要。只要意识到您的需求是非标准的并导致不可互操作的标记。确实,如果没有为您的特殊需求提供合理的解释,读者就会觉得您不了解命名空间,而且坦率地说,继续强调这一点,您不知道自己在做什么。
标签: python xml python-2.7 lxml