XmlElement: Release Notes

Mit Version 0.2.0 unterstützt XmlElement, siehe XmlElement - ein einfacher XML-Generator (und Parser), nun das Erzeugen von XmlElements (und damit XML-Dateiinhalten) aus einem POJO-like Object:

from XmlElement import XmlElement as X

xml = X.from_object(node_name='CustomerFavorites', data={
        '@xmlns:a': 'http://a.ecmind.ch/test/',
        '@xmlns:b': 'http://b.ecmind.ch/test/',
        'Customer': {
            '@id': 'SISBEN',
            'Name': 'Sisko',
            'Firstname': 'Benjamin',
            'a:Items': {'Item': [
                        {'b:No': 123456, 'Name': 'Bio-mimetic gel', '@clearance_required': True},
                        {'b:No': 234567, 'Name': 'Self-sealing stem bolts'}
                ]
            },
        'Customer': {
            '@id': 'NERKIR',
            'Name': 'Kira',
            'Firstname': 'Nerys',
            'a:Items': {'Item': [
                        {
                            'b:No': 345678, 
                            'Name': 
                            'Photon torpedo target system', 
                            '@clearance_required': True,
                            '': 'This is the info text for a modern photon torpedos targeting system'
                        }
                ]
                }
            }
        },
        'Count': 2
    }
)

print(xml)

Dies ergibt (zzgl. pretty print):

<CustomerFavorites xmlns:a="http://a.ecmind.ch/test/"
    xmlns:b="http://b.ecmind.ch/test/">
    <Customer id="SISBEN">
        <Name>Sisko</Name>
        <Firstname>Benjamin</Firstname>
        <a:Items>
            <Item clearance_required="true">
                <b:No>123456</b:No>
                <Name>Bio-mimetic gel</Name>
            </Item>
            <Item>
                <b:No>234567</b:No>
                <Name>Self-sealing stem bolts</Name>
            </Item>
        </a:Items>
        <Customer id="NERKIR">
            <Name>Kira</Name>
            <Firstname>Nerys</Firstname>
            <a:Items>
                <Item clearance_required="true">This is the info text for a modern photon torpedos targeting system<b:No>345678</b:No>
                    <Name>Photon torpedo target system</Name>
                </Item>
            </a:Items>
        </Customer>
    </Customer>
    <Count>2</Count>
</CustomerFavorites>

Download via pip install --upgrade XmlElement aus PyPi:

Mit Version 0.2.1 unterstützt XmlElement nun das Unwandeln in ein POJO-like-Objekt:

from XmlElement import XmlElement as X

test_dict1 = {
    '@xmlns:a': 'http://a.ecmind.ch/test/',
    '@xmlns:b': 'http://b.ecmind.ch/test/',
    'Customer': {
        '@id': 'SISBEN',
        'Name': 'Sisko',
        'Firstname': 'Benjamin',
        'a:Items': {'Item': [
                    {'b:No': 123456, 'Name': 'Bio-mimetic gel',
                        'price_in_latinum_strips': 1999999.95, '@clearance_required': True},
                    {'b:No': 234567, 'Name': 'Self-sealing stem bolts',
                        'price_in_latinum_strips': 5.50, 'discount': -1.5}
                    ]
                    },
        'Customer': {
            '@id': 'NERKIR',
            'Name': 'Kira',
            'Firstname': 'Nerys',
            'a:Items': {'Item': [
                    {
                        'b:No': 345678,
                        'Name':
                        'Photon torpedo target system',
                        '@clearance_required': True,
                        'price_in_latinum_strips': 2499.95,
                        '': 'This is the info text for a modern photon torpedos targeting system'
                    }
            ]
            }
        }
    },
    'Count': 2
}

test_xml1 = X.from_object(node_name='CustomerFavorites', data=test_dict1)
test_dict2 = test_xml1.to_dict()
test_xml2 = X.from_object(node_name='CustomerFavorites', data=test_dict2)
test_dict3 = test_xml2.to_dict()
print(test_dict1)
print('---')
print(test_dict2)
print('---')
print(test_dict3)

Ausgabe (beachte: Unterschiede bei Reihenfolge sowie Arrays/Lists, die nicht erkannt werden können, wenn sie nur aus einem Element bestehen):

{'@xmlns:a': 'http://a.ecmind.ch/test/', '@xmlns:b': 'http://b.ecmind.ch/test/', 'Customer': {'@id': 'SISBEN', 'Name': 'Sisko', 'Firstname': 'Benjamin', 'a:Items': {'Item': [{'b:No': 123456, 'Name': 'Bio-mimetic gel', 'price_in_latinum_strips': 1999999.95, '@clearance_required': True}, {'b:No': 234567, 'Name': 'Self-sealing stem bolts', 'price_in_latinum_strips': 5.5, 'discount': -1.5}]}, 'Customer': {'@id': 'NERKIR', 'Name': 'Kira', 'Firstname': 'Nerys', 'a:Items': {'Item': [{'b:No': 345678, 'Name': 'Photon torpedo target system', '@clearance_required': True, 'price_in_latinum_strips': 2499.95, '': 'This is the info text for a modern photon torpedos targeting system'}]}}}, 'Count': 2}
---
{'@xmlns:a': 'http://a.ecmind.ch/test/', '@xmlns:b': 'http://b.ecmind.ch/test/', 'Customer': {'@id': 'SISBEN', 'Name': 'Sisko', 'Firstname': 'Benjamin', 'a:Items': {'Item': [{'@clearance_required': True, 'b:No': 123456, 'Name': 'Bio-mimetic gel', 'price_in_latinum_strips': 1999999.95}, {'b:No': 234567, 'Name': 'Self-sealing stem bolts', 'price_in_latinum_strips': 5.5, 'discount': -1.5}]}, 'Customer': {'@id': 'NERKIR', 'Name': 'Kira', 'Firstname': 'Nerys', 'a:Items': {'Item': {'@clearance_required': True, 'b:No': 345678, 'Name': 'Photon torpedo target system', 'price_in_latinum_strips': 2499.95, '#': 'This is the info text for a modern photon torpedos targeting system'}}}}, 'Count': 2}
---
{'@xmlns:a': 'http://a.ecmind.ch/test/', '@xmlns:b': 'http://b.ecmind.ch/test/', 'Customer': {'@id': 'SISBEN', 'Name': 'Sisko', 'Firstname': 'Benjamin', 'a:Items': {'Item': [{'@clearance_required': True, 'b:No': 123456, 'Name': 'Bio-mimetic gel', 'price_in_latinum_strips': 1999999.95}, {'b:No': 234567, 'Name': 'Self-sealing stem bolts', 'price_in_latinum_strips': 5.5, 'discount': -1.5}]}, 'Customer': {'@id': 'NERKIR', 'Name': 'Kira', 'Firstname': 'Nerys', 'a:Items': {'Item': {'@clearance_required': True, 'b:No': 345678, 'Name': 'Photon torpedo target system', 'price_in_latinum_strips': 2499.95, '#': 'This is the info text for a modern photon torpedos targeting system'}}}}, 'Count': 2}

Der Download ist wie üblich via pip von PyPi.org möglich:

1 „Gefällt mir“

Version 0.2.3 ist nun dagegen gewappnet, Objektattribute mit gleichnamigen Kindelementen zu überschreiben:

from XmlElement import XmlElement

xml = XmlElement.from_object(node_name='test', data={ 
        'firstname': 'Max', 
        'name': 'Säntis'
    }
)

print(xml)              # <-- <test><firstname>Max</firstname><name>Säntis</name></test>
print(xml.firstname[0]) # <-- <firstname>Max</firstname>
print(xml.name[0])      # <-- t 

Die überrasschende Antwort auf xml.name[0] = t rührt daher, dass name ein nun geschütztes Objektattribut ist und damit nicht auf einen gleichnamigen Knoten im XML verzweigt. Der Buchstabe 0 im .name test ist dabei das t.

Download wie gewohnt via PyPi.org:

1 „Gefällt mir“

XmlElement in Version 0.3.0 bringt einige kleinere und grössere Änderungen:

  • Neuerdings werden Textwerte von XmlElement oder die Werte von Attributen aus nicht-String-Typen implizit konvertiert. Das übergeben von Werten mit str() u. ä. sollte damit in den meisten Fällen unnötig werden.
    • Aus bool-Werten wird true oder false.
    • ints werden als Text aus Dezimalzahlen gerendert.
    • Ebenso werden float-Werte als Dezimalzahlen interpretiert.
  • Der Testcode und Type hints wurden korrigiert.
  • Ein Fehler bei der Erkennung von #-Kindelementen wurde bei der Umwandung aus einem dict zu einem XmlElement korrigiert.
  • Neu lassen sich XmlElemente direkt in eine Datei (oder einen Dateideskriptor) schreiben mit der to_file(...)-Methode.
  • Umgekehrt gilt das gleiche mit from_file(...)
  • Das bisherige Feature to Kindknoten mit dem Punktoperator zu erreichen wurde zugunsten des type checkings entfernt. Damit ist folgendes nicht mehr möglich und muss ersetzt werden:
print(xml.Child1[0].Child2[0].text)       # alt
print(xml['Child1'][0]['Child2'][0].text) # neu