2
\$\begingroup\$

For some time now, I've been using a pattern which I think could be done more elegantly. I have a lot of XML files that need to be represented in a Django views. My current approach is like this:

I get a XML response from an API which gives me several documents.

First I define a mock class like this:

class MockDocument:
    pass

Then I write an XPath expression that gives me a list of the document nodes:

from lxml import etree   
with open("xmlapiresponse.xml", "r") as doc:
    xml_response = doc.read()   
tree = etree.fromstring(xml_response)                                                        
document_nodes = tree.xpath("//documents/item") 

Now I iterate over the different documents and their fields using nested for-loops:

# list for storing the objects
document_objects = []
for document in document_nodes:
    # create a MockDocument for each item returned by the API
    document_object = MockDocument()    
    for field in document:
        # store the corresponding fields as object attributes
        if field.tag == "something":
            document.something = field.text
    document_objects.append(document)         

Now I can pass the list of mock objects to a Django view and represent them in the template in whichever way I want. Could this be done in a simpler fashion, though?

\$\endgroup\$
4
\$\begingroup\$

Using a generator function gives you some flexibility. You don't have to create a list.

def generate_documents( document_nodes ):

    for document in document_nodes:
        # create a MockDocument for each item returned by the API
        document_object = MockDocument()    
        for field in document:
            # store the corresponding fields as object attributes
            if field.tag == "something":
                document.something = field.text
        yield  document_object 

You can do this of the list object is somehow important.

document_objects = list( generate_documents( document_nodes ) )

Or, more usefully, this

for d in generate_documents( document_nodes ):
    ... process the document ...

Which never actually creates a list object.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.