What is BadgerFish?

BadgerFish is a convention for translating an XML document into a JSON object. Once you've got your XML document represented as a JSON object, it's easy to manipulate from within Javascript. If you're familiar with PHP's SimpleXML extension, think of BadgerFish as aiming for a similar goal: making it simpler to do common manipulations of XML documents with a predictable structure.

How does it work?

Here are the rules:

  1. Element names become object properties
  2. Text content of elements goes in the $ property of an object.

    <alice>bob</alice>

    becomes

    { "alice": { "$" : "bob" } }
  3. Nested elements become nested properties

    <alice><bob>charlie</bob><david>edgar</david></alice>

    becomes

    { "alice": { "bob" : { "$": "charlie" }, "david": { "$": "edgar"} } }
  4. Multiple elements at the same level become array elements.

    <alice><bob>charlie</bob><bob>david</bob></alice>

    becomes

    { "alice": { "bob" : [{"$": charlie" }, {"$": "david" }] } }
  5. Attributes go in properties whose names begin with @.

    <alice charlie="david">bob</alice>

    becomes

    { "alice": { "$" : "bob", "@charlie" : "david" } }
  6. Active namespaces for an element go in the element's @xmlns property.
  7. The default namespace URI goes in @xmlns.$.

    <alice xmlns="http://some-namespace">bob</alice>

    becomes

    { "alice": { "$" : "bob", "@xmlns": { "$" : "http:\/\/some-namespace"} } }
  8. Other namespaces go in other properties of @xmlns.

    <alice xmlns="http:\/\/some-namespace" xmlns:charlie="http:\/\/some-other-namespace">bob</alice>

    becomes

    { "alice": { "$" : "bob", "@xmlns": { "$" : "http:\/\/some-namespace", "charlie" : "http:\/\/some-other-namespace" } } }
  9. Elements with namespace prefixes become object properties, too.

    <alice xmlns="http://some-namespace" xmlns:charlie="http://some-other-namespace"> <bob>david</bob> <charlie:edgar>frank</charlie:edgar> </alice>

    becomes

    { "alice" : { "bob" : { "$" : "david" , "@xmlns" : {"charlie" : "http:\/\/some-other-namespace" , "$" : "http:\/\/some-namespace"} } , "charlie:edgar" : { "$" : "frank" , "@xmlns" : {"charlie":"http:\/\/some-other-namespace", "$" : "http:\/\/some-namespace"} }, "@xmlns" : { "charlie" : "http:\/\/some-other-namespace", "$" : "http:\/\/some-namespace"} } }

How can I use it?

  1. If you're a PHP user and you want to translate XML to BadgerFish-formatted JSON on your own web site, download BadgerFish.php, a PHP class that translates an XML document into a BadgerFish-formatted JSON string. BadgerFish.php depends on Services_JSON, which you can download from http://mike.teczno.com/JSON.tar.gz.
  2. If you're a Ruby user, check out Cobra vs Mongoose by Paul Battley, which translates between XML and Ruby Hash objects using the BadgerFish convention. Combined with the Ruby JSON library, it can translate between XML, Ruby Hash Objects, and JSON.

What's broken and/or left to do?

  1. BadgerFish throws away the text content of elements if the text content is entirely whitespace. It also doesn't provide a way to get the different text bits in an element whose content is a mix of text and children (e.g. <p>Some text <strong>is important</strong>.</p>). Perhaps those different text bits should be made available in $1, $2, etc.
  2. BadgerFish populates @xmlns in all elements where a namespace is active, not just in the elements where the namespace is declared. This may be overkill for people who don't care that much about namespaces. Perhaps allow a format that ignores @xmlns altogether?
  3. Adaptors to create BadgerFish-formatted JSON strings in languages other than PHP.
  4. Adaptors to turn BadgerFish-formatted JSON objects back into XML-formatted strings and/or DOM objects.

Where do I send comments or complaints?

Tell me (David Sklar) what you think. The name is Brian's fault.

Anything else I should know?

Jacob Smullyan wrote a related Python model, pesterfish, which he describes as: "a quick Python module which is uses the same xml object model as the dominant xml module in the Python world, elementtree; Some elementtree implementation (there are several) and simplejson are required. BTW, elementtree stores namespaces in Clark notation: {http://www.w3.org/1999/xhtml}br and so does this.". pesterfish also lets you round trip XML through it without any data loss.

Raphaël Szwarc wrote a Lua implementation of BadgerFish.