I currently working on DOM and i wonder how can change the place of tags data
for example
I have created element:
propElement = document.createElement("prop");
The prop is opening the tag.
Then
propElement.setAttribute("name", "name1");
propElement.setAttribute("name2", "name2");
The problem is that despite i put the set method name2 after name1 I will see in the tag name2 before name1.
How can I change the order ?
(Note; I'm using a Java DOM API, not JavaScript.)
You can't, the order of attributes on elements is not significant. In fact, in a live DOM, there is no order. Order only seems to exist in relation to the serialized form of a DOM (e.g., HTML markup and the like). And even then, the order doesn't have any meaning except in relation to invalid text (more below).
Attributes are basically simple properties of an object (the DOM element to which they're attached). There is absolutely no order to them, and in fact the representation of them in the DOM is a NamedNodeMap which is "...not maintained in any particular order."
It's important to remember that the DOM describes an object model. The serialized form of a DOM may be textual (for instance, an HTML document defining a DOM), but the DOM is not. In an HTML document, since it's linear text (top-to-bottom, left-to-right), naturally the text defining one attribute has to precede the text describing another, but that does not imply any kind of order to the attributes in the resulting DOM object, because they have no order at all. So this:
<div a="1" b="2">...</div>
describes exactly the same element as this:
<div b="2" a="1">...</div>
The resulting element is a div which has an attribute a with the value 1 and an attribute b with the value 2.
This is exactly the same as setting properties on an object in program source. Consider some hypothetical obj with x and y properties. This code:
obj.a = 1;
obj.b = 2;
...results in exactly the same object as this code:
obj.b = 2;
obj.a = 1;
...provided a and b really are simple fields (not hidden function calls that may have side effects), which is true of attributes in the DOM.
There is one small way in which attribute order in the textual (serialized) form of a DOM may be significant, and it's only related to invalid text: If the same attribute is specified more than once, only the first value given is used, because it's invalid to specify the same attribute more than once. The values are not combined, and the subsequent value doesn't overwrite the previous one. The first one, only, is used.
So this invalid HTML:
<div class="foo" class="bar">...</div>
...actually results in a div with class "foo" ("bar" is not present at all). But this is just a coping mechanism for dealing with invalid serialized forms.
Related
Say I have the following XML file:
<a xmlns:foo="http://foo"></a>
I need to check whether the prefix foo is bound to http://foo or not. Whereby not bound could indicate that the said prefix does not exist at all or is bound to some other namespace URI.
I already have a library that takes a Document object and an XPath expression and returns a (possibly empty) List of Nodes that exist at that XPath.
So what would be an expression that would check for the presence of a prefix foo in the top-most element (document element) bound to the namespace http://foo and that would yield one node for the above XML and zero nodes for the following XMLs:
<a xmlns:fooX="http://foo"></a>
and
< xmlns:foo="http://fooX"></a>
I tried, as a first step, to just get the value of that attribute using:
/*[#*[local-name()='foo']]
... but it seems that prefix-binding attributes are handled differently from "normal" attributes.
If you want to do it with XPath then you have to use the namespace axis: /*[namespace::foo[. = 'http://foo']]. DOM Level 3 might provide different ways treating the namespace declarations as attributes and resolving prefixes, see http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI.
Given following XML, we are using JXPathContext to create Java object out of it.
<fb1:Activity fb2:metadata="Activity1">
</fb1:Activity>
<fb21:ActivityMetadata fb2:id="Activity1">
<fb1:Response>XXXX</fb1:Response>
</fb1:ActivityMetadata>
reading the value -
String responseCode = context.getValue("metadata[1]/Response/value");
This is working as expected. Now lets say for instance, the reference from Activity to ActivityMetadata is missing. What can we do to read the response value in such case? It is guaranteed that there can only be one ActivityMetadata element at max in the XML.
Incomplete XML - need to parse this
<fb1:Activity fb2:metadata="">
</fb1:Activity>
<fb21:ActivityMetadata>
<fb1:Response>XXXX</fb1:Response>
</fb1:ActivityMetadata>
The path you're giving us doesn't match the document you're showing us.
Ignoring that for a moment:
XML doesn't constrain the tree at all; that's done by the XML Schema (if there is one) and/or the applications which process that kind of document. Only the folks who defined this particular kind of document, or the schema, or the code can tell you whether there are any guarantees about only one ActivityMetadata being present or what it means if there's more than one.
XML is pure syntax. Meaning is someone else's problem.
Im trying to make a program which will build a tree from xml document via SAX parser.
But in result names of tags build sucsessful , but in attributes I see only attribute of last tag.
What is wrong with code?
Print to tree is in tag.toString()
Try to change line 48 into:
Tag t = new Tag(eName, new org.xml.sax.helpers.AttributesImpl(attrs));
I guess the problem is that you are storing the Attributes instance for each Tag, and that the Attributesinstance is reused for each each call to startElement() invokation. Thus, every Tag will will see the same attributes instance with the same content, that of the last one constructed by the parser. You will have to create a copy (or a Map or something else) of the actual attributes for each Tag.
Assuming some xml like
<foo>
<bar>test</bar>
</foo>
Evaluating an expression with returnType = String like
/foo/bar
will return "test". However, I'd like to get the serialized xml instead, so something like
<bar>test</bar>
should be returned instead. As I can not check for the returnType in java's xpath implementation (xerces), I cannot simply get an object as result and if it indeed is a node, convert it to serialized xml.
Note: I don't know whether the expression will actually return a node, a string, a number or whatever so I cannot provide an appropriate return type to the eval function except string which, as my problem states, returns the text content and not the serialized xml.
So I am curious -> is there either a java- or (preferred) a xpath-way (function?) to get serialized xml for type string instead of the text children of the selected node?
thanks!
Alex
use the xpath return type XPathConstants.NODE and then you can serialize the returned Node yourself.
Now, you are right to observe that it's difficult to discover the return type of the result; this is a real design weakness of JAXP.
If it's a problem to you, consider using Saxon's s9api interface, which returns XdmValue objects whose type you can interrogate; you also get XPath 2.0 access as a bonus.
As Michael Kay answered, this is difficult in JAXP (the native Java interface).
In Mr Kay's Saxon library's s9api API (see Evaluating XPath Expressions using s9api), once you've called XPathSelector.evaluate() or XPathSelector.evaluateSingle() you can get the XML serialisation by calling XdmValue.toString().
However, if the XPath selected an attribute (e.g. //#name) you will still get the XML serialisation, e.g. name="value". You can call XdmItem.getStringValue(), but for elements that method will return the same values you're already seeing - the textual content of the element, not the serialisation. I've posted separately about how to distinguish between attributes and elements returned from Saxon s9api.
This question already has answers here:
Order of XML attributes after DOM processing
(12 answers)
Closed 9 years ago.
When writing in java the following:
Element fieldEl = targetDocument.createElement("field");
fieldEl.setAttribute("Wine","Marlo");
fieldEl.setAttribute("Beer","Corona");
The order of adding the attributes are not kept in the result XML file.
How can I control the order of the attribute inside XML Element (so it will be easy for human being to read...) ??
There is no defined order for attribute nodes according to the DOM standard:
Objects implementing the NamedNodeMap interface are used to represent collections of nodes that can be accessed by name. Note that NamedNodeMap does not inherit from NodeList; NamedNodeMaps are not maintained in any particular order. Objects contained in an object implementing NamedNodeMap may also be accessed by an ordinal index, but this is simply to allow convenient enumeration of the contents of a NamedNodeMap, and does not imply that the DOM specifies an order to these Nodes.
(emphasis added) and neither in the XML standard:
Note that the order of attribute specifications in a start-tag or empty-element tag is not significant.
I don't think, that many DOM implementations support ordering of attributes at all. You'd have to write your own serialization mechanism in order to achieve ordering (no pun intended).