从一个父级获取子节点名称

时间:2015-04-02 20:51:21

标签: python xml parsing

给出以下XML结构

<cmap>
   <tableVersion version="0" />
   <cmap_format_4 platformID="0" platEncID="3" language="0">
      <map code="0x20" name="space" />
      <!-- SPACE -->
      <!--many, many more characters-->
   </cmap_format_4>
   <cmap_format_0 platformID="1" platEncID="0" language="0">
      <map code="0x0" name=".notdef" />
      <!--many, many more characters again-->
   </cmap_format_0>
   <cmap_format_4 platformID="0" platEncID="3" language="0">
      <!--"cmap_format_4" again-->
      <map code="0x20" name="space" />
      <!-- SPACE -->
      <!--more "map" nodes-->
   </cmap_format_4>
</cmap>

我正在尝试逐步获取cmap_format_0级别的节点名称列表以及它们下面的所有codename节点。

预期结果

cmap_format_4
0x0   null
0xd   CR
ox20  space
etc...

cmap_format_0
0x0   notdef
0x1   notdeaf
etc...

到目前为止我已经

charactersByFontString = "CODE\tCHAR DESC\n"
tree = ET.parse(xmlFile)
root = tree.getroot()

for map in root.iter("map"):
    charactersByFontString += map.attrib["code"] + "\t"
    charactersByFontString += map.attrib["name"] + "\n"

这是我的所有代码和名称。但我无法得到c_format_n的名称。

for child in root:
    print child.child

不起作用,因为tableversion是它的第一个孩子,是自我关闭的,没有孩子。 (另外我不确定是否将一堆child个节点串在一起甚至可以工作。)child.sibling给我一个错误。如何以cmap_format_n格式获取这些孩子?

2 个答案:

答案 0 :(得分:1)

我可以建议XSLT转换您的输入XML吗?

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text" encoding="UTF-8" indent="yes" />

    <xsl:template match="/cmap">
        <xsl:apply-templates select="*[starts-with(name(), 'cmap_')]" />
    </xsl:template>

    <xsl:template match="*[starts-with(name(), 'cmap_')]">
        <xsl:value-of select="name()" />
        <xsl:text>&#xA;</xsl:text>
        <xsl:apply-templates select="map" />
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>

    <xsl:template match="map">
        <xsl:apply-templates select="@code" />
        <xsl:text>&#x9;</xsl:text>
        <xsl:apply-templates select="@name" />
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

输出(http://xsltransform.net/bFDb2Cu

cmap_format_4
0x20    space

cmap_format_0
0x0 .notdef

cmap_format_4
0x20    space

可以在over here找到如何在Python中使用XSLT的示例。

我并不是说它不能以你尝试的方式完成(DOM遍历) - 它绝对可以 - XSLT更适合这项任务。

答案 1 :(得分:0)

import xml.etree.ElementTree as ET

xmlFile = "pytest.xml"

out = "CODE\tCHAR DESC\n"

tree = ET.parse(xmlFile)
root = tree.getroot()

for child in root:
    if child.tag[:4] == 'cmap':
        out += child.tag + '\n'
        for grandchild in child:
            out += grandchild.attrib["code"] + '\t'
            out += grandchild.attrib["name"] + '\n'
        out += '\n'

print(out)