Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constants like pi or expressions like nothing, are not interpreted but result in "pi" and "nothing" #22

Closed
Kevin-Mattheus-Moerman opened this issue Dec 15, 2023 · 2 comments

Comments

@Kevin-Mattheus-Moerman
Copy link
Contributor

If I do something like this:

breadNode = XML.Element("bread",nothing)
push!(foodNode, breadNode)

breadNode = XML.Element("bread",pi)
push!(foodNode, breadNode)

breadNode = XML.Element("bread",Base.MathConstants.catalan)
push!(foodNode, breadNode)

The XML will contain:

<bread>nothing</bread>
<bread>π</bread>
<bread>catalan</bread>

The correct behaviour should be:

<bread></bread>
<bread>3.141592653589793</bread>
<bread>0.9159655941772</bread>

So it looks like constants and expressions like nothing are currently converted to "strings" based on their name, rather than being interpreted first? Note I also tried using XML.Text(pi) or XML.Text(nothing), but the same happens.

The context is that I am trying to create an "add element node" function called aen, to remove the clutter from my code. Here is one attempt where I was hoping to use an optional amount of args and kwargs.

function aen(main_node::Node,sub_node_name::String, args...; kwargs...)
    sub_node = XML.Element(sub_node_name, args...; kwargs...)
    push!(main_node, sub_node)
    return sub_node
end

However, if one now uses the following, one still gets <bread>nothing</bread>:

aen(foodNode,"bread")

So when args... is empty Julia passes a nothing which is currently again producing the string "nothing" in the XML file at the moment.

A workaround for constants seems to be to force them to be interpreted e.g. by multiplying by 1:

breadNode = XML.Element("bread",1.0*pi)

Sidenote, not sure if breadNode = XML.Element("bread",[]) should produce the following either:

<bread>Any[]</bread>

This may highlight a general issue in interpreting the XML.Text entry.

Thanks for your help!

@Kevin-Mattheus-Moerman
Copy link
Contributor Author

Kevin-Mattheus-Moerman commented Dec 15, 2023

Just learned this behaviour is probably inherited from the print function, and it seems the same for the string function. I'm new to Julia, but this seems like odd behaviour to me.

julia> print(pi)
π
 
julia> print(nothing)
nothing
 
julia> string(pi)
"π"
 
julia> string(nothing)
"nothing"
 
julia> string(5)
"5"
 
julia> string(1.0*pi)
"3.141592653589793"

My quick and dirty fix now checks if the thing is nothing:

function aen(main_node::Node,sub_node_name::String, args...; kwargs...)
    if isnothing(args)
        sub_node = XML.Element(sub_node_name; kwargs...)    
    else
        sub_node = XML.Element(sub_node_name, args...; kwargs...)    
    end
    push!(main_node, sub_node)
    return sub_node
end

@joshday
Copy link
Member

joshday commented Dec 16, 2023

Most things don't have a text/xml representation. Adding the necessary show method would be type piracy, so XML.jl falls back to string(x).

This has the drawback of what you're describing here, but the benefit of not hitting errors all the time for things that you would expect to work:

julia> repr("text/xml", 1)
ERROR: MethodError: no method matching show(::IOBuffer, ::MIME{Symbol("text/xml")}, ::Int64)

Think of this as the rule for how XML.jl writes a given x:

showable("text/xml", x) ? repr("text/xml", x) : repr(x)

I like having a clear rule vs. special cases for different types, so I'm going to close this issue.

@joshday joshday closed this as completed Dec 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants