Retrieve attribute names and values with Python / lxml and XPath

后端 未结 2 833
青春惊慌失措
青春惊慌失措 2021-01-19 03:21

I am using XPath with Python lxml (Python 2). I run through two passes on the data, one to select the records of interest, and one to extract values from the data. Here is a

2条回答
  •  后悔当初
    2021-01-19 04:19

    I was wrong in my assertion that I was not going to use Python. I found that the lxml/etree implementation is easily extended to that I can use the XPath DSL with modifications.

    I registered the function "dictify". I changed the XPath expression to :

    dictify('@id|@height|@weight|weight|height')
    

    The new code is:

    from lxml import etree
    
    xml = """
    
        
        150
        
    
    """
    
    def dictify(context, names):
        node = context.context_node
        rv = []
        rv.append('__dictify_start_marker__')
        names = names.split('|')
        for n in names:
            if n.startswith('@'):
                val =  node.attrib.get(n[1:])
                if val != None:
                    rv.append(n)
                    rv.append(val)
            else:
                children = node.findall(n)
                for child_node in children:
                    rv.append(n)
                    rv.append(child_node.text)
        rv.append('__dictify_end_marker__')
        return rv
    
    etree_functions = etree.FunctionNamespace(None)
    etree_functions['dictify'] = dictify
    
    
    parsed = etree.fromstring(xml)
    nodes = parsed.xpath('/records/row')
    for node in nodes:
        print node.xpath("dictify('@id|@height|@weight|weight|height')")
    

    This produces the following output:

    ['__dictify_start_marker__', '@id', '1', '@height', '160', '@weight', '80', '__dictify_end_marker__']
    ['__dictify_start_marker__', '@id', '2', '@weight', '70', 'height', '150', '__dictify_end_marker__']
    ['__dictify_start_marker__', '@id', '3', '@height', '140', '__dictify_end_marker__']
    

提交回复
热议问题