elm-xml-parser icon indicating copy to clipboard operation
elm-xml-parser copied to clipboard

Handle attribute's namespaces

Open gorghoa opened this issue 8 years ago • 1 comments

Hi, I’m using your lib (thanks!) to (in pseudo pipeline) :

string svg
 |> parse
 |> do stuff with the nodes (add attribute, reorder, etc)
 |> render the svg to the dom via the elm-lang/Svg  + elm-lang/virtual-dom

My problem lies in the third pipe ”render the svg to the dom via the elm-lang/Svg + elm-lang/virtual-dom”: To create namespaced attributes correctly in dom elements correctly, I have to use VirtualDom.attributeNS.

Say a tag like: <use xlink:href="#great" … />. the xlink:href is a namespaced attribute, the namespace is declared in the svg tag like <svg xmlns:xlink="http://www.w3.org/1999/xlink">.

Once parsed with elm-xml-parser, to render this node in view, I would love to do it like this:

{-| Render a SVG node 
-}
displayNode : Node -> Svg msg
displayNode pnode =
    case pnode of
        XmlParser.Element name attrs child ->
            node name (attrs |> List.map convertToAttributes) (child |> List.map displayNode)

        XmlParser.Text leaf ->
            text leaf

{-| Convert parsed SVG attributes to DOM SVG attributes
-}
convertToAttributes : XmlParser.Attribute -> Svg.Attribute msg
convertToAttributes attr =

     -- Today, this is not possible: we only have the name and the value of the attribute, not the namespace
    case attr of
         Attribute name value ->
             attribute name value
         NamespacedAttribute namespace name value ->
             attributeNS namespace name value

I know this would be a BC break, since it would leads to changing the type of Attribute from type alias Attribute = { name : String, value : String } to something like maybe:

type XMLAttribute
        = Attribute { name: String, value : String }
        | AttributeNS { name: String, value: String, namespace: String }

type Node
    = Element String (List XMLAttribute) (List Node)
    | Text String

or just adding a namespace: Maybe String to the existing Attribute record.

If you are interested in this feature, I could give it a try. Just let me know which solution you prefer.

Refs

  • http://package.elm-lang.org/packages/elm-lang/virtual-dom/latest/VirtualDom#attributeNS
  • https://developer.mozilla.org/en/docs/Namespaces

gorghoa avatar Jun 22 '17 21:06 gorghoa

Thanks for the feedback! (I just saw Slack too)

I'm not sure I can spend my time for this anytime soon. So feel free to do a PR!

Some thoughts I'm thinking now are:

  • At least you are not blocked. you can separate the tag name by :.
  • Introducing namespaces may expand the scope this library should cover. I don't have enough knowledge about XML namespaces for now. So I'm wondering what would be the best API for it. (Always accounting namespaces? Should we consider if the namespace is correctly declared? Is validation needed when parsing? etc.)

or just adding a namespace: Maybe String to the existing Attribute record.

I think this one is better. Having pure String should work well too.

jinjor avatar Jun 23 '17 14:06 jinjor