2

I am creating an XML document using django, and looking at the XSD schema, a lot of the tags may or may not be needed.

Like so:

<GenericCustomerPaymentDetails>
    <PayPalID>{{purchase.customer.ppid}}</PayPalID>
    <BankAccountNumber>{{purchase.customer.ban}}</BankAccountNumber>
    <SortCode>{{purchase.customer.sc}}</SortCode>
    <CreditCardNumber>{{purchase.customer.ccn}}</CreditCardNumber>
    <BitCoinAddress>{{purchase.customer.bitcoin}}</BitCoinAddress>
</GenericCustomerPaymentDetails>

Now, I know how to individually specify that a tag may or may not exist (wrap in an if/endif tags), but it's going to triple the size of the document, and double the amount of maintenance to do this:

<GenericCustomerPaymentDetails>
    {% if purchase.customer.ppid %}
    <PayPalID>{{purchase.customer.ppid}}</PayPalID>
    {% endif %}
    {% if purchase.customer.ban%}
    <BankAccountNumber>{{purchase.customer.ban}}</BankAccountNumber>
    {% endif %}
    {% if purchase.customer.sc %}
    <SortCode>{{purchase.customer.sc}}</SortCode>
    {% endif %}
    {% if purchase.customer.ccn %}
    <CreditCardNumber>{{purchase.customer.ccn}}</CreditCardNumber>
    {% endif %}
    {% if purchase.customer.bitcoin %}
    <BitCoinAddress>{{purchase.customer.bitcoin}}</BitCoinAddress>
    {% endif %}
</GenericCustomerPaymentDetails>

If there a more elegant way to do this? Is there a way to bulk apply an if exists to the value and the tag? (bonus points if the solution can accommodate stags [self-closing tags])

The only way I can think of doing this is make these payment methods into a list of objects on the json like so

purchase.customer:[
    {tag_name:"PayPalID",tag_content:"pay.me.monies@geemail.com"},
    {tag_name:"BitCointAddress",tag_content:"http://blockexplorer.com/address/1PC9aZC4hNX2rmmrt7uHTfYAS3hRbph4UN"},
]

And then loop over them. But that will require extra data manipulation to get into this format, and I'd rather not have to go through that effort (if looks like this is the way to go, if you already have data that way, though.).

Community
  • 1
  • 1
Pureferret
  • 6,477
  • 14
  • 72
  • 149

1 Answers1

4

You can write a custom filter that checks if the value exists and wraps it using the correct XML tag. For example:

def default_xml_tag(value, arg):
    if value:
        return "<{0}>{1}</{0}>".format(arg, value)
    else:
        return ""

and simply write

{{purchase.customer.ppid | default_xml_tag:"PayPalID" }}

in your templates.

For details on how to register your filter, refer to the (excellent) Django docs.

Selcuk
  • 45,843
  • 11
  • 87
  • 90
  • That's more or less what I've just written! Thanks for pointing out how simple it is. The only difference I have is I'm using a [one line if statement](http://stackoverflow.com/a/394814/1075247). – Pureferret May 18 '15 at 14:19