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

Allow creation of new Element specifying name and namespace #133

Open
paolofulgoni opened this issue Feb 25, 2015 · 13 comments
Open

Allow creation of new Element specifying name and namespace #133

paolofulgoni opened this issue Feb 25, 2015 · 13 comments

Comments

@paolofulgoni
Copy link

A very nice feature is the new element creation specifying only the tag name (e.g. $("p")).

I think it may be useful to allow the creation of an element specifying both the tag name and the namespace: $(String name, String namespace).

In my case, I need to create SVG element, so instead of writing something like

$("<rect xmlsn="http://www.w3.org/2000/svg"></rect>")

I could write something more concise:

$("rect", "http://www.w3.org/2000/svg")
// or using a constant, defined somewhere
$("rect", SVG_NAMESPACE);

Of course, this is something that doesn't exist in jQuery, so if you want to keep the API similar this proposal doesn't make sense.

@lukaseder
Copy link
Member

I can see the use-case, but the method is already "taken":

public static Match $(String name, String content)

Also, I don't see namespaces as first-class API citizens in this way, but there's certainly room for improvement. Perhaps a namespace setter on a Match?

// Set the default namespace on a match
$("rect").xmlns("http://www.w3.org/2000/svg");
// -> <rect xmlns="http://..."/>

// Set the prefixed namespace on a match
$("rect").xmlns("svg", "http://www.w3.org/2000/svg");
// -> <rect xmlns:svg="http://..."/>

@lukaseder
Copy link
Member

Of course this xmlns() method would merely be a convenience method for attr():

$("rect").attr("xmlns", "http://www.w3.org/2000/svg");

@paolofulgoni
Copy link
Author

The namespace setter you proposed would be great, but I'm afraid it wouldn't work.

I'm not a namespace expert at all, but I found that merely setting the xmlns attribute after the element creation doesn't change the namespace.

    Element first = $("<rect xmlns=\"http://www.w3.org/2000/svg\" />").get(0);
    Element second = $("rect").attr("xmlns", "http://www.w3.org/2000/svg").get(0);

    System.out.println(first.getLocalName()); // rect
    System.out.println(second.getLocalName()); // null
    System.out.println(first.getNamespaceURI()); // http://www.w3.org/2000/svg
    System.out.println(second.getNamespaceURI()); // null

(EDIT: sorry I wrote the wrong comments, now they're correct)

I also managed to create a "namespace-aware" element by calling Document.createElementNS() (obviously).

@lukaseder
Copy link
Member

but I found that merely setting the xmlns attribute after the element creation doesn't change the namespace

Hmm, good point, I hadn't thought of that. Ah, these namespaces are such a mess :)

Perhaps, a new org.joox.Namespace type could be introduced and reused across the API when dealing with namespaces. The following API would certainly make sense:

$(String name, Namespace namespace)

I'm sure there are other caveats waiting down the line, though.

@paolofulgoni
Copy link
Author

That could be a good idea!

As far as I understood, both elements and attributes can "belong" to a namespace.
So a new API for attribute could be useful too.

.attr(String name, String value, Namespace namespace)

Something I don't understand is where the prefix come from, so I made this simple test:

Element noPrefix = $("<rect xmlns=\"http://www.w3.org/2000/svg\" />").get(0);
System.out.println(noPrefix.getPrefix()); // null
System.out.println(noPrefix.getLocalName()); // rect
System.out.println(noPrefix.getNamespaceURI()); // http://www.w3.org/2000/svg

Element withPrefixBad = $("<rect xmlns:svg=\"http://www.w3.org/2000/svg\" />").get(0);
System.out.println(withPrefixBad.getPrefix()); // null
System.out.println(withPrefixBad.getLocalName()); // rect
System.out.println(withPrefixBad.getNamespaceURI()); // null

Element withPrefixGood = $("<svg:rect xmlns:svg=\"http://www.w3.org/2000/svg\" />").get(0);
System.out.println(withPrefixGood.getPrefix()); // svg
System.out.println(withPrefixGood.getLocalName()); // rect
System.out.println(withPrefixGood.getNamespaceURI()); // http://www.w3.org/2000/svg

Element noPrefix2 = $().document().createElementNS("http://www.w3.org/2000/svg", "rect");
System.out.println(noPrefix2.getPrefix()); // null
System.out.println(noPrefix2.getLocalName()); // rect
System.out.println(noPrefix2.getNamespaceURI()); // http://www.w3.org/2000/svg

Element withPrefix2 = $().document().createElementNS("http://www.w3.org/2000/svg", "svg:rect");
System.out.println(withPrefix2.getPrefix()); // svg
System.out.println(withPrefix2.getLocalName()); // rect
System.out.println(withPrefix2.getNamespaceURI()); // http://www.w3.org/2000/svg

@lukaseder
Copy link
Member

So a new API for attribute could be useful too.

Yes, absolutely!

Something I don't understand is where the prefix come from

I'm not sure what you mean...?

@paolofulgoni
Copy link
Author

Sorry for not being clear...

Please consider this SVG image as example: http://dev.w3.org/SVG/tools/svgweb/samples/svg-files/car.svg (cool, isn't it?)
The main <svg> tag "declares" several namespaces with the associated prefix. Let's consider inkscape for example. This prefix is then used along the document, without specifying again the related namespace.
What is not clear to me is how to create such a document with DOM (or with jOOX). In my previous comment I tried to create an element in a namespace with or without prefix, but what about this:

  • how to create an element which declares several namespaces, like the <svg> tag in this example? Are they just attributes?
  • how to create a node/attribute using a namespace prefix declared in a parent element, like inkscape:collect="always" in the example?

@lukaseder
Copy link
Member

I see now, but unfortunately, I don't know. At Data Geekery, when we created jOOX, we only operated with namespace-less XML. Namespaces are a rather big pain, so we've tried to avoid them. Obviously, this means that jOOX isn't really ready for proper usage of namespaces.

In org.w3c.dom, there is an org.w3c.dom.NameList type, but I don't see it being used anywhere.

Intuitively, I'd say that namespace declaration attributes are just ordinary attributes with implied semantics (such as the id attribute), but then again, DOM has its ways...

I'm sorry for not being too responsive here, it's just that I don't really know what is the best way to proceed, or if we should proceed at all

@paolofulgoni
Copy link
Author

Yes, NameList seems to be something not really used in DOM implementations.
For example, it is obsolete in Gecko: https://developer.mozilla.org/en/docs/Web/API/NameList.

Anyway, it seems that createElementNS and createAttributeNS methods are the only way to create a namespace-aware element/attribute in DOM. So if jOOX had methods which map to those ones, it would be certainly positive.

@lukaseder
Copy link
Member

OK, so now we know the constraints. Unfortunately, I'm rather busy with jOOQ right now, so I won't be able to make this a priority for jOOX. I mean, we could get something to work quickly, but it would risk not being very good...

@paolofulgoni
Copy link
Author

No problem, of course. I can create the namespace-aware elements anyway with the jQuery style:

$("<rect xmlsn="http://www.w3.org/2000/svg"></rect>")

Thanks for considering the proposal.

@lukaseder lukaseder modified the milestones: Version 1.3.0, Version 1.4.0 Apr 8, 2015
@lukaseder lukaseder modified the milestones: Version 1.4.0, Version 1.5.0 May 3, 2016
@lukaseder lukaseder modified the milestones: Version 1.6.0, Version 1.7.0 Nov 30, 2017
@pmihalcin
Copy link

@lukaseder you mentioned in this issue:

At Data Geekery, when we created jOOX, we only operated with namespace-less XML.

How do you avoid name conflicts? https://www.w3schools.com/XML/xml_namespaces.asp

@lukaseder
Copy link
Member

@pmihalcin Well, we don't have any conflicts. It's possible to use XML without namespaces or with single, implied namespaces. XML with mixed namespaces is quite a different beast, and has, so far, been mostly out of scope for jOOX.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants