Remove xmlns attribute - java

I have an xml
<XML>
<Client xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="2.34.00" ></Client>
</XML>
How to remove all the attributes in the Client tag in Java.
I used earlier
Element element = (Element) doc.getElementsByTagName("Client").item(0);
element.removeAttribute("Version");
element.removeAttribute("xmlns:xsi");
The Version attribute was removed from the Client tag. But xmlns:xsi attribute was NOT removed.
Does anybody faced any similar issue or know how to approach this problem.

You should getOwnerDocument() for node "Client" and do renameNode(nodeClient,null,"Client");
NB: removeAttribute removes "xmlns:xsi", but namespace is stored in Node "Client" and can appear at Document to string regeneration moment.

Related

How to remove an specific xml attribute from org.w3c.dom.Document

I have this XML:
<Body xmlns:wsu="http://mynamespace">
<Ticket xmlns="http://othernamespace">
<Customer xlmns="">Robert</Customer>
<Products xmlns="">
<Product>a product</>
</Products>
</Ticket>
<Delivered xmlns="" />
<Payment xlmns="">cash</Payment>
</Body>
I am using Java to read it as a DOM document. I want remove the empty namespace attributes (i.e., xmlns=""). Is there any way to do that?
You need to understand that xmlns is a very special attribute. Basically, the xmlns="" is so that your Customer element is in the "unnamed" namespace, rather than the http://othernamespace namespace (and likewise for other elements which would otherwise inherit a default namespace from their ancestors).
If you want to get rid of the xmlns="", you basically need to put the elements into the appropriate namespace - so it's changing the element name. I don't think the W3C API lets you change the name of an element - you may well need to create a new element with the appropriate namespaced-name, and copy the content. Or if you're responsible for creating the document to start with, just use the right namespace.

Dom4j selectNodes(arg) don't give list of nodes

I am using DOM4j for XML work in java,
my xml is like this:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<abcd name="ab.catalog" xmlns="http://www.xyz.com/pqr" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xyz.com/pqr ./abc.xyz.xsd">
<efg>
......
</efg>
<efg>
.....
</efg>
</abcd>
then,
List<Node>list = document.selectNodes("/abcd/efg");
gets the size of list zero. I feel it's due to namespace specified in the xml.
I tried a lot but cn't get success.
Unprefixed element names in XPath expressions refer to elements that are not in a namespace - they do not take account of the "default" xmlns="..." namespace declared on the document. You need to declare a prefix for the namespace in the XPath engine and then use that prefix in the expression. Here is an example inspired by the DOM4J javadocs:
Map uris = new HashMap();
uris.put("pqr", "http://www.xyz.com/pqr");
XPath xpath = document.createXPath("/pqr:abcd/pqr:efg");
xpath.setNamespaceURIs(uris);
List<Node> nodes = xpath.selectNodes(document);
Modify your code :
List<Node>list = document.selectNodes("//abcd/efg");

OAI Jaxen XPath problem

I'm having big problems with Xpath evaluation using Jaxen.
Here's part of XML i'm evaluating on:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
<responseDate>2011-05-31T13:04:08+00:00</responseDate>
<request metadataPrefix="oai_dc" verb="ListRecords">http://citeseerx.ist.psu.edu/oai2</request>
<ListRecords>
<record>
<header>
<identifier>oai:CiteSeerXPSU:10.1.1.1.1484</identifier>
<datestamp>2009-05-24</datestamp>
</header>
<metadata>
<oai_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
<dc:title>Winner-Take-All..</dc:title>
<dc:relation>10.1.1.134.6077</dc:relation>
<dc:relation>10.1.1.65.2144</dc:relation>
<dc:relation>10.1.1.54.7277</dc:relation>
<dc:relation>10.1.1.48.5282</dc:relation>
</oai_dc:dc>
</metadata>
</record>
<resumptionToken>10.1.1.1.2041-1547151-500-oai_dc</resumptionToken>
</ListRecords>
</OAI-PMH>
I'm using Jaxen because in my use case it's much faster then Apache implementation. I'm using W3C DOM for XML representation.
I need to select all record arguments, and then on selected nodes evaluate other xpaths (it's needed because of my processing architecture).
I'm selecting all record nodes (this works):
/OAI-PMH/ListRecords/record
Then on every selected record node I'm evaluating other xpaths to get needed data:
Select identifier text value (this works):
header/identifier/text()
Select title text value (this does NOT work):
metadata/oai_dc:dc/dc:title/text()
I've registered namespaces prefixes with their URIs (oai_dc and dc). I also tried other xpaths but none of them work:
metadata/dc/title/text()
metadata//dc:title/text()
I've read other stackoverflow questions about xpaths, namespaces and solution to add prefix "oai" with URI "http://www.openarchives.org/OAI/2.0/". I tried adding that "oai:" prefix to nodes without defined prefix but as result I even didn't select record nodes. Any ideas what I'm doing wrong?
Solution:
Problem was about parser (thanks jasso). It wasn't set to be namespace aware - after changing that setting everything works fine, as expected.
I can't see how the XPath expression /OAI-PMH/ListRecords/record can possibly select anything, since your document does not have a {}OAI-PMH element, only a {http://www.openarchives.org/OAI/2.0/}OAI-PMH element. See http://jaxen.codehaus.org/faq.html

How to set namespace only on first tag with XOM?

I am using XOM to build XML documents in Java.
I have created a simple XML document, and I want an XML namespace. But when I set the namespace on the first tag, an empty namespace is set on the childs like xmlns="", how can I get rid of this behaviour? I only want xmlns on the first tag.
I want this XML:
<request xmlns="http://my-namespace">
<type>Test</type>
<data>
<myData>test data</myData>
</data>
</request>
But this is the XML document output from XOM
<request xmlns="http://my-namespace">
<type xmlns="">Test</type>
<data xmlns="">
<myData>test data</myData>
</data>
</request>
This is my Java XOM code:
String namespace = "http://my-namespace";
Element request = new Element("request", namespace);
Element type = new Element("type");
type.appendChild("Test");
request.appendChild(type);
Element data = new Element("data");
request.appendChild(data);
Element myData = new Element("myData");
myData.appendChild("test data");
data.appendChild(myData);
Document doc = new Document(request);
doc.toXML();
This works for me. However, I'm a bit puzzled as to why the Element objects don't inherit the namespace of their parents, though. (Not an XML nor XOM expert)
Code:
String namespace = "http://my-namespace";
Element request = new Element("request", namespace);
Element type = new Element("type", namespace);
type.appendChild("Test");
request.appendChild(type);
Element data = new Element("data", namespace);
request.appendChild(data);
Element myData = new Element("myData", namespace);
myData.appendChild("test data");
data.appendChild(myData);
Document doc = new Document(request);
System.out.println(doc.toXML());
Output:
<?xml version="1.0"?>
<request xmlns="http://my-namespace">
<type>Test</type>
<data>
<myData>test data</myData>
</data>
</request>
I ran into the same problem, and Google lead me here.
#Michael - That's what it says in the javadoc, yes, but unfortunately, that's not how it works when you implement it. The child elements will continue to get blank xmlns attributes unless you do Catchwa's implementation.
Catchwa's implementation works just fine. Only the element I tell it to have a namespace, has a namespace. All empty xmlns attributes are gone. It's strange.
Is it a bug? I can't seem to figure that part out. Or is it just the way XOM works?
Don't confuse namespaces and namespace declarations. The namespace is an intrinsic property of each element. The namespace declaration is the `xmlns' attribute. They are not the same thing, although they are connected. When you create an element, you set its namespace, not its namespace declaration.
In the XOM data model namespaces are not attributes. They are an intrinsic property of the element itself. There is no rule in XML that requires children of an element to be in the same namespace as the parent. Indeed theoretically every element in the document could be in a different namespace.
In XOM you specify the namespace of an element or attribute at the same time you specify the local name. When you create an element, the element initially has no parent so there's no way for XOM to default to giving the element the same namespace as its parent, even if that's what was wanted (and it's not).
When the document is serialized the namespaces are represented by xmlns and xmlns:*prefix* attributes. XOM figures out where to put these elements to match the namespaces you've assigned to each element. Just specify the namespace you want for each element in your code, and let XOM figure out where to put the namespace declarations.
In XOM you can add a namespace declaration to the root element.
Here's a short example with three different namespaces:
final String NS_XLINK = "http://www.w3.org/1999/xlink";
final String NS_OTHER = "http://other.com";
Element root = new Element("root", "http://root.com");
root.addNamespaceDeclaration("xlink", NS_XLINK);
root.addNamespaceDeclaration("other", NS_OTHER);
root.addAttribute(new Attribute("xlink:href", NS_XLINK, "http://somewhere.com"));
root.appendChild(new Element("other:alien", NS_OTHER));
Document doc = new Document(root);
System.out.println(doc.toXML());
which produces this result (with additional line breaks inserted for readability):
<?xml version="1.0"?>
<root
xmlns="http://root.com"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:other="http://other.com"
xlink:href="http://somewhere.com">
<other:alien />
</root>

XML parsing with java dom parser converts xml declaration into elements

Here is the xml file that I need to process as part of my assignment.
<?xml-stylesheet type="text/xsl" href="people.xsl"?>
<People>
<Person>
`...`
</Person>
`...`
</People>
I am using the "javax.xml.parsers.DocumentBuilderFactory" to create a dom parser. After parsing, the resultant document does not have People at the root but some root having children as xml-stylesheet and People.
Looks like this can be avoided.
<?xml-stylesheet ... ?> is not an XML declaration. It is a Processing Instruction (PI), and the DOM spec says that a Document node may contain zero or more of them.
One approach would be to code your application to deal appropriately with (e.g. ignore) an PI's in the Document node. Alternatively, just use the Document node's documentElement attribute / getter to get the root Element directly.

Categories

Resources