Skip to content

Help building XML documents programmatically #21

Closed
@Kevin-Mattheus-Moerman

Description

@Kevin-Mattheus-Moerman

First of all thanks for making this toolbox in pure Julia, it looks really promising!

It looks like this still needs a lot of documentation. In particular it would be great if more on the code-based construction of the XML file could be added, especially when it comes to perhaps using a "top down" approach.

Below is an attempt to building something. I would be grateful if you could point out if this is heading in the right direction. I am a bit of a beginner at Julia so still learning the ropes and felt I head to reverse engineering the below from reading the code itself.

So I set out to build something like this in Julia

<?xml encoding="UTF-8" version="1.0"?>
<food>
  <fruit>
    <banana price="0.7774726194631364" id="1" state="ripe">Delicious</banana>
    <banana price="0.3684100013220113" id="2" state="ripe">Delicious</banana>
    <banana price="0.8749562951626388" id="3" state="ripe">Delicious</banana>
    <banana price="0.8953197455414397" id="4" state="ripe">Delicious</banana>
    <banana price="0.1578191472435514" id="5" state="ripe">Delicious</banana>
    <banana price="0.21085070334788591" id="6" state="ripe">Delicious</banana>
    <banana price="0.9056195858301516" id="7" state="ripe">Delicious</banana>
    <banana price="0.3665784312744298" id="8" state="ripe">Delicious</banana>
    <banana price="0.6778572670222438" id="9" state="ripe">Delicious</banana>
    <banana price="0.44119524986389513" id="10" state="ripe">Delicious</banana>
  </fruit>
</food>

This is how I did it:

using XML # Call XML package

# Define file name
filenameOut = "/home/kevin/DATA/Julia/JuliaAdventures/sample2.xml"

# Define "template" banana node
bananaNodeTemplate = Node(XML.NodeType(5),"banana",Dict([("id", 1), ("state", "ripe"), ("price", 1.25)]),nothing,XML.Text("Delicious"))

# Define fruit node with a single template banana node for the moment 
fruitNode = Node(XML.NodeType(5),"fruit",nothing,nothing,bananaNodeTemplate)

# Define food node with children
foodNode = Node(XML.NodeType(5),"food",nothing,nothing,fruitNode)

# Define declaration: <?xml version="1.0" encoding="UTF-8"?>
declarationNode = Node(XML.NodeType(2),nothing,Dict([("version", "1.0"), ("encoding", "UTF-8")]),nothing,nothing)

# Define document level
doc = Node(XML.NodeType(3),nothing,nothing,nothing,[declarationNode,foodNode])

# Add additional banana nodes
for q=1:10    
    idStr = string(q)
    priceStr = string(rand(1)[1])
    
    bananaNode = deepcopy(bananaNodeTemplate)
    bananaNode.attributes["id"]=idStr    
    bananaNode.attributes["price"]=priceStr

    if q == 1
        fruitNode.children[1]=bananaNode # Overwrite the first child
    else
        push!(fruitNode::Node,bananaNode) # Simple add the new children
    end
end

# Write to XML file
XML.write(filenameOut::String, doc)

It works but does not generalise nicely yet to what I want. This seems mostly "bottom up" rather than "top down". What I would like to do, or what I feel would be most intuitive is to start with the document level, then add food if we encounter it, then add fruit if we encounter that, then add more and more banana entries as we encounter them. Perhaps the user could define some kind of structure array which I could then parse nested level by nested level to build the XML file. With the current code it seems I have to (unless I am wrong) start at the lowest level. I have attempted to define the food level with empty children first for instance, and then to edit it to have fruit as children... but I got stuck. Is there such a thing as an "empty child" to which one can push entries to create a non-empty children set?

Any help would be great. Thanks again.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions