I'm trying to create an array list out of an XML file.
In fact, I need to read a user input(which would be one of the elements) and return a certain node value.Here's the XML file:
<?xml version="1.0" ?>
- <types>
- <type id="Nourriture" taxe="0.1">
<element>pomme</element>
<element>fraise</element>
<element>fromage</element>
<element>viande rouge</element>
</type>
- <type id="Matiere Premiere" taxe="0.2">
<element>fer</element>
<element>polypropylene</element>
</type>
- <type id="Element Solide" taxe="0.3">
<element>voiture</element>
<element>planche surf</element>
<element>pistolet</element>
</type>
</types>
What I'm asked for is to see element, then depending on that, I need to return the "taxe" value.
I literally tried most things to do that, until I noticed my only solution is putting them inside an array /array list as follows:
`ArrayList arraylistobject = new ArrayList();
arraylistobject.add(....);`
etc...
Any thoughts on how to do this?
One obvious way is to use XPath:
//element[text()="fer"]/parent::type/string(#taxe)
(search for element whose text is "fer", select it's parent type, get string value of the parent's taxe attribute)
Related
I am using Java to extract values using XPath. I was able to extract elements under the element fields but the elements under records are not returned.
XML is as follows:
<?xml version="1.0" ?>
<qdbapi>
<action>****</action>
<errcode>0</errcode>
<errtext>No error</errtext>
<qid>****</qid>
<qname>****</qname>
<table>
<fields>
<field id="19" field_type="text" base_type="text">
</field>
</fields>
<records>
<record>
<f id="6">1</f>
</record>
</records>
</table>
</qdbapi>
Code below:
XMLDOMDocObj.selectNodes("//*[local-name()='fields']")//21 fields returned
XMLDOMDocObj.selectNodes("//*[local-name()='records']")//no records are returned
XML must have a single root element; yours has two: fields and records.
Wrap them in a single common root to get the results you expect.
Also, if your XML has no namespaces, there's no reason to defeat them. Instead of
//*[local-name()='records']
use
//records
See also
How does XPath deal with XML namespaces?
Why must XML documents have a single root element?
What is the difference between root node, root element and document element in XML?
I have an XML Document which contains XML elements containing attributes from which I would like to get it's value and store it in a Hashmap.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<Nodes>
<Node name="test1">
<mou>
<line3>hello</line3>
</mou>
</Node>
<Node name="test2">
<mou>
<line3>hello</line3>
</mou>
</Node>
<InputNode name="Chance">
<Test>
<RoundTo>100</RoundTo>
</Test>
</InputNode>
<InputNode name="total" />
</Nodes>
I'd like to parse this xml and retrieve the values attributes from all the elements named 'Node' and store it in a map object. So from the example above I would get
[name=test1,name=test2]
The problem is with maps the keys must be unique. How can I accomplish my goal using Java?
Sorry, I got your question wrong. You can parse the xml already. You want to store it in a map. You can create objects out of all the nodes. Node { nodeName, attribute1, attribute2} then you can save it as a map by {key,value} = {name, nodeObj}
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.
I am using the DOM parser. I have to parse the following XML:
<abc>
<type action="">
<code>test</code>
<value>001</value>
</type>
<type action="">
<code>test2</code>
<value>002</value>
</type>
</abc>
so, depending on the value field under the type field, I have to fill in the action attribute in the type field. I am a bit stumped. I am able to get the value of the value field, but I don't know how to go back and add the attribute.
Any help will be appreciated a lot!!!
thanks!
To go back, just save a reference to the type Element before you traverse to its value child. (assuming you visited it already).
to change the value, use the setAttribute() method.
edit:
Alternate method: from the value text node, call getParentNode() twice (once to get back to the value element & once to get back to the type element), then call setAttribute() after you do any necissary casting.
try something like
nodelist = doc.getElementsByTagName("value");
for (Element element : nodelist) {
Element parent = element.getParentNode()
parent.setAttribute("action", "attrValue");
}
I need an efficient way to convert XML to meaningful domain objects in Java. Below is a selection of XML that I have to work with (some values have been obscured). Here are the basic constraints I have to work with:
There is no schema to work with. Auto-generated schemas don't turn out well because of the variable "nesting."
Any given domain-object can contain 0-* domain-object tags
Any given domain-object can contain 0-* value tags.
Not all nesting is created equal. In some cases, the "key" of a value includes implicit nesting. For example, "config[0].cbs" indicates a collection of config objects, each with a different value for .cbs
Changing the XML structure may not be possible.
The "represents" attribute indicates a type.
The "nestedKey" attribute indicates a variable name inside a type.
These XML files can be quite large.
I've tried using JAXB, but things aren't working out because of the "generic-ness" of the tags. Perhaps my JAXB-fu is insufficient. The current implementation (I inherited this) is SAX, but it doesn't actually work. I've looked at XStream, but it seems to assume some semantic structure to the tags.
I would like a least-code, most-flexible, most-extendable approach to generate meaningful domain objects. I'd like to avoid nesting HashMaps if possible (that's part of the current solution that doesn't work). Creative, hack-y, or clever ideas are welcome as well as striaght-forward "duh" answers too.
XML Snippet:
<?xml version="1.0"?>
<domain-objects>
<types language="C++">
<type prefix="bool" language-representation="bool" />
<type prefix="char" language-representation="char" />
<type prefix="domain_object" language-representation="opti::DomainObject" />
<type prefix="domain_object" language-representation="DomainObject" />
<type prefix="double" language-representation="double" />
<type prefix="float" language-representation="float" />
...
</types>
<domain-object key="(unique object id)" represents="PerfSuite">
<domain-object key="(unique object id)" nestedKey="testCore" represents="PerfTestCore">
<value key="suiteUuid" type="stl_string">(unique object id)</value>
<value key="suiteName" type="stl_string">(some name)</value>
<value key="suiteId" type="int">(some number)</value>
<value key="suiteDeleted" type="bool">false</value>
</domain-object>
<domain-object key="(unique object id)" nestedKey="testResults" represents="PerfTestResults">
<domain-object key="(unique object id)" nestedKey="services_0" represents="PerfServiceResult">
<domain-object key="(unique object id)" nestedKey="stepResults_0" represents="PerfStepResult">
<value key="ir.max" type="int64">(some number)</value>
<value key="ftd.avg" type="float">(some number)</value>
<value key="ftd.max" type="float">(some number)</value>
...
</domain-object>
<value key="duration" type="uint">(some number)</value>
<value key="flow" type="uint16">(some number)</value>
...
<value key="config[1].flrThreshold" type="float">(some number)</value>
<value key="config[1].fdvPercent" type="float">(some number)</value>
<value key="index" type="uint16">(some number)</value>
<value key="config[0].cbs" type="uint64">(some number)</value>
<value key="svlanVid" type="uint16">(some number)</value>
<value key="config[1].availThreshold" type="float">(some number)</value>
...
No one tool will solve this problem for you entirely.
JAXB might still be the right answer for the parsing part. You will have to do the final pass yourself if you are looking to have each of the domain objects translated into your actual domain objects.
JAXB wont be able to parse out "float" to determine that it needs to lookup the types table to find that float maps to float. Finding "config[1].fdvPercent" in your object is also beyond its capabilities.
From what I can see, you have a fairly consistent document structure that could be described by a schema. Writing this in XML schema, or annotating classes should be straightforward.
domain-objects = types+, domain-object+
domain-object = domain-object*, value*
From here, you have your work cut out for you. I suspect that you will need a number of things:
per-type parsing of the strings in each element so you can get the value for each
a mapping from the string value of types to the per-type parsers (it looks like you might need an extra mapping step to go from the C++? types you use to the Java type)
a parser for the value keys so that you can find the variable to apply the value to
some reflection to instantiate objects and set the value in the created object
I can't guess what nestedKey or represents means to you. Those might require additional steps.