将XML元素转换为其JSON等效元素,反之亦然

lxml2json的Python项目详细描述


lxml2json

lxml2json是一个python包,它将xml元素转换为它们的json等价物,反之亦然。 有许多选项可将数据转换为所需格式:

  • 重命名标记
  • 忽略元素
  • 在树中移动元素
  • 始终将数据表示为列表
  • 提供空元素的值

安装:

    pip install lxml2json

用法:

    from lxml2json import convert
    from pprint import pprint as pp

    xml = '''
    <parent>
        <c1>a</c1>
        <c1>b</c1>
        <c1>c</c1>
        <c2>
            <gc1>d</gc1>
            <gc2>e</gc2>
            <gc3>f</gc3>
        </c2>
        <c2>
            <gc1>g</gc1>
            <gc2>h</gc2>
            <gc3>i</gc3>
        </c2>
        <c3>
            <gc1>j</gc1>
            <gc1>k</gc1>
            <gc1>l</gc1>
        </c3>
        <c4/>
    </parent>'''

    d = convert(xml)
    pp(d)
    {'parent': {'c1': ['a', 'b', 'c'],
                'c2': [{'gc1': 'd', 'gc2': 'e', 'gc3': 'f'},
                       {'gc1': 'g', 'gc2': 'h', 'gc3': 'i'}],
                'c3': {'gc1': ['j', 'k', 'l']},
                'c4': None}}

选项

lxml2json提供以下可选参数来修改转换行为或输出数据格式:

  • 顺序:布尔型,默认为false。指定是否将输出生成为OrderedDict。

  • 备注文本:默认为无。指定给不包含子元素和文本值的元素的值。

  • 始终列表:默认为无。允许将xpath查询的规范应用于将 使所有匹配的元素存储为列表。这对于创建确定性数据结构很有用。 请参见下面的示例。

  • 忽略:默认为无。允许将xpath查询的规范应用于将导致 所有匹配的元素都将被忽略。

  • 重命名:默认为无。允许通过提供元组/元组列表(包含匹配元素的xpath查询)来重命名标记 使用指定所需标记的字符串。例如,请参见下面的内容。

  • 移动:默认为无。提供将元素移动到层次结构中所需位置的选项。用例:扁平化 深深嵌套的结构。需要元组/包含匹配元素的xpath查询的元组列表,以及xpath查询 (相对于匹配元素的位置)移动元素的位置。请参见下面的示例

操作顺序为:移动、重命名、忽略。这允许您通过将子元素移动到同一层次结构级别,重命名原始元素,然后忽略它来基本上用子元素替换元素。

始终列表

lxml2json的处理逻辑总是试图将元素表示为字典,除非有多个 具有相同标记的同级元素,在这种情况下,它必须将对象表示为列表,因为词典需要唯一的键。

这会在整个json数据结构中产生差异,因为xml的某些部分可以表示为列表和 具有相同标记的其他节可以表示为字典或文本值,具体取决于具有相同标记的同级项的数目。

考虑以下示例:

    >>> from lxml2json import convert
    >>> from pprint import pprint as pp
    >>> 
    >>> xml = '''
    ... <parent>
    ...     <c1>
    ...         <num>1</num>
    ...         <num>2</num>
    ...         <num>3</num>
    ...     </c1>
    ...     <c2>
    ...         <num>4</num>
    ...         <num>5</num>
    ...         <num>6</num>
    ...     </c2>
    ...     <c3>
    ...         <num>7</num>
    ...     </c3>
    ... </parent>
    ... '''
    >>>

默认情况下,lxml2json将此xml对象表示为:

    >>> pp(convert(xml))
    {'parent': {'c1': {'num': ['1', '2', '3']},
                'c2': {'num': ['4', '5', '6']},
                'c3': {'num': '7'}}}

注意,"num"键的值包含在前两个实例的列表中,但最后一个实例的值只是它的本机值7。 这种行为是预期的,在许多情况下,它的功能和XML结构的表示都非常好。但是,它可以呈现 迭代生成的json对象时遇到的挑战,因为可能需要额外的逻辑来处理值是否包含在列表中。

为了允许更确定的结构,lxml2json允许您提供将应用于输入的xml的xpath查询,从而产生任何匹配的元素 存储为列表,而不考虑相同兄弟标记的数量。

在本例中,xpath查询:"//num"将匹配所有"num"元素,从而使所有此类元素将其值存储在列表中。

让我们看看这一点:

    >>> 
    >>> pp(convert(xml, alwaysList=".//num"))
    {'parent': {'c1': {'num': ['1', '2', '3']},
                'c2': {'num': ['4', '5', '6']},
                'c3': {'num': ['7']}}}
    >>> 

请注意第三个"num"值现在是一个列表,类似于前两个实例。

您可以提供任意数量的xpath查询,可以是查询列表,也可以是逗号分隔的值字符串。无论哪种情况,都将标记匹配的元素。

忽略

"ignore"选项允许指定要忽略的元素。 例子:

>>> from lxml2json import convert
>>> from pprint import pprint as pp
>>>
xml = '''
<parent>
    <son>
        <grandson>Thomas</grandson>
        <grandson>Robert</grandson>
        <granddaughter>Karen</granddaughter>
    </son>
</parent>
'''
>>> 
>>> pp(convert(xml))
{'parent': {'son': {'granddaughter': 'Karen',
                    'grandson': ['Thomas', 'Robert']}}}
>>> 
>>> pp(convert(xml, ignore=".//granddaughter"))
{'parent': {'son': {'grandson': ['Thomas', 'Robert']}}}
>>> 

通过指定xpath查询"//grandaughter",lxml2json将在转换时忽略带有该标记的任何元素。

移动

"move"选项允许数据结构的变异以匹配所需的状态。一个用例是"展平"嵌套结构。

需要提供元组/元组列表,每个元组都包含一个匹配元素的xpath查询以及一个相应的xpath查询(相对于匹配元素的位置),指定层次结构中移动数据的位置。

示例:

xml = """
<children>
    <child>
        <name>Joey</name>
        <age>7</age>
        <favorite>
            <things>
                <toys>
                    <toy>legos</toy>
                    <toy>playstation</toy>
                    <toy>bike</toy>
                </toys>
            </things>
        </favorite>
    </child>
</children>"""

#default result
>>> pp(convert(xml))
{'children': {'child': {'age': '7',
                        'favorite': {'things': {'toys': {'toy': ['legos',
                                                                 'playstation',
                                                                 'bike']}}},
                        'name': 'Joey'}}}
>>> 

#perhaps we want a flattened child dictionary
>>> pp(convert(xml, move=(".//toy", "./../../../.."), ignore=".//favorite"))
    {'children': {'child': {'age': '7',
                            'name': 'Joey',
                            'toy': ['legos', 'playstation', 'bike']}}}

从json转换为xml

lxml2json提供一个"reverse"函数,为输入的dictionary对象生成一个xml元素(或字符串)。

注意:如果输入的字典有多个顶级k:v对,或者顶级键的值是一个列表,那么将创建一个"根"元素,以便 格式化的XML结构,需要一个根元素。

选项

只有一个布尔选项:"text",默认为false。当设置为true时,reverse函数将输出一个打印良好的xml元素字符串。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
jframe为什么JAVA paint()方法不起作用?   java Guice:将ContainerRequestContext注入拦截器   java如何优雅地关闭Spring JMS MessageListenerAdapter   java如何在Spring中设置快照隔离级别   Java中的安卓平台独立信任存储路径   java无法在eclipse中运行hello world程序   java Sinch空指针问题   使用Java将JSON流式传输到BigQuery   java从“大数据”中选择什么Swing控件?   java通过对象字段过滤/排序集合?   java将数据从活动传递到另一个活动中的片段   java访问打包在jar文件中的文档   Java获取事件的大小。getDragboard()。getFiles()。流()。映射(文件::长度)。toString());   java Android libgdx:启动程序图标按下后,启动屏幕不会立即显示   java如何在Google App Engine灵活环境中配置oracle jdk   java有没有办法减少这些行?   Java:客户端socket不读取第二行,在终止符行之后保持打开状态   java以编程方式获取api 29上的所有APK文件   java ActionBar按钮不显示