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");
}
Related
<employees>
<employee>
<firstName>Lokesh</firstName>
<lastName>Gupta</lastName>
<department>
<id>101</id>
<name>IT</name>
</department>
</employee>
</employees>
I wanted to get the elements name using Xpath..
I need to count the number of elements that i am getting using count(//employees/*) and count(//employees/employee/department/*)
it is returning count of each parent..
I need to get the element names as well //employees/employee/*/name() to get the elements name FirstName, LastName and Department..
also (//employees/employee/department/*/name()) to return name and id.. but it is showing error javax.xml.transform.TransformerException: Unknown nodetype: name .
You want to get the elements names (not the value of it). name() has to appear the first.
Since javax only supports XPath 1.0, you can use :
concat(name(//employees/employee/*[1]),",",name(//employees/employee/*[2]),",",name(//employees/employee/*[3]))
Output : firstName,lastName,department
concat(name(//employees/employee/department/*[1]),",",name(//employees/employee/department/*[2]))
Output : id,name
If you don't know the number of child for each parent element, you should use a loop approach. First, count and store the number of child (count(//employees/employee/*)), then make a loop where you increase the position index ([i]) at each iteration //employees/employee/*[i] i=i+1.
My XML file
<classifications>
<classification sequence="1">
<classification-scheme office="" scheme="CS" />
<section>G</section>
<class>01</class>
<subclass>R</subclass>
<main-group>33</main-group>
<subgroup>365</subgroup>
<classification-value>I</classification-value>
</classification>
<classification sequence="2">
<classification-scheme office="" scheme="CS" />
<section>G</section>
<class>01</class>
<subclass>R</subclass>
<main-group>33</main-group>
<subgroup>3415</subgroup>
<classification-value>A</classification-value>
</classification>
<classification sequence="1">
<classification-scheme office="US" scheme="UC" />
<classification-symbol>324/300</classification-symbol>
</classification>
<classification sequence="2">
<classification-scheme office="US" scheme="UC" />
<classification-symbol>324/307</classification-symbol>
</classification>
</classifications>
I want to parse the value with following condition
required all the classification-symbol element value along with condition office="US"
I tried with below XPath,
NodeList usClassification = (NodeList)xPath.compile("//classifications//classification//classification-scheme[#office=\"US\"]//classification-symbol//text()").evaluate(xmlDocument, XPathConstants.NODESET);
but I'm getting an empty result set,
System.out.println(usClassification.getLength()); //its becomes zero
This XPath (written on two lines to ease readability),
/classifications/classification[classification-scheme/#office='US']
/classification-symbol/text()
will select the classification-symbol text of the classification elements with classification-scheme #office attribute value equal to US:
324/300
324/307
as requested.
classification-symbol is not a child of classification-scheme - they are siblings. Use following-sibling axis to get from "scheme" to "symbol" instead:
//classifications/classification/classification-scheme[#office=\"US\"]/following-sibling::classification-symbol/text()
Both are used to get the WebElement value in between tags.
Is my assumption right? If wrong, please elaborate.
<input attr1='a' attr2='b' attr3='c'>foo</input>
getAttribute(attr1) you get 'a'
getAttribute(attr2) you get 'b'
getAttribute(attr3) you get 'c'
getText() with no parameter you can only get 'foo'
getAttribute() -> It fetches the text that contains one of any attribute in the HTML tag. Suppose there is an HTML tag like
<input name="Name Locator" value="selenium">Hello</input>
Now getAttribute() fetches the data of the attribute of 'value', which is "Selenium".
Returns:
The attribute's current value or null if the value is not set.
driver.findElement(By.name("Name Locator")).getAttribute("value") //
The field value is retrieved by the getAttribute("value") Selenium WebDriver predefined method and assigned to the String object.
getText() -> delivers the innerText of a WebElement.
Get the visible (i.e. not hidden by CSS) innerText of this element, including sub-elements, without any leading or trailing whitespace.
Returns:
The innerText of this element.
driver.findElement(By.name("Name Locator")).getText();
'Hello' will appear
<img src="w3schools.jpg" alt="W3Schools.com" width="104" height="142">
In above html tag we have different attributes like src, alt, width and height.
If you want to get the any attribute value from above html tag you have to pass attribute value in getAttribute() method
Syntax:
getAttribute(attributeValue)
getAttribute(src) you get w3schools.jpg
getAttribute(height) you get 142
getAttribute(width) you get 104
getText(): Get the visible (i.e. not hidden by CSS) innerText of this
element, including sub-elements, without any leading or trailing
whitespace.
getAttribute(String attrName): Get the value of a the given attribute of the element.
Will return the current value, even if this has been modified after
the page has been loaded. More exactly, this method will return the
value of the given attribute, unless that attribute is not present, in
which case the value of the property with the same name is returned
(for example for the "value" property of a textarea element). If
neither value is set, null is returned. The "style" attribute is
converted as best can be to a text representation with a trailing
semi-colon. The following are deemed to be "boolean" attributes, and
will return either "true" or null: async, autofocus, autoplay,
checked, compact, complete, controls, declare, defaultchecked,
defaultselected, defer, disabled, draggable, ended, formnovalidate,
hidden, indeterminate, iscontenteditable, ismap, itemscope, loop,
multiple, muted, nohref, noresize, noshade, novalidate, nowrap, open,
paused, pubdate, readonly, required, reversed, scoped, seamless,
seeking, selected, spellcheck, truespeed, willvalidate Finally, the
following commonly mis-capitalized attribute/property names are
evaluated as expected: "class" "readonly"
getText() return the visible text of the element.
getAttribute(String attrName) returns the value of the attribute passed as parameter.
I am trying to implement client side validation in Struts 2. my theme is xhtml. The javascript generated is not able to validate my code. After debugging , I found that Struts is using the following notation to refer the elements.
form = document.getElementById(<form id>);
service = form.elements['service'];
the point is that service is coming as undefined.
when I checked that form.elements is null; However if I access form using document.formname i am able to see the fields in elements collection.
I am thinking document.forms[0] is returning the same object as document.getElementById(formid). What is the difference?
The form element can access fields by name, for this purpose you should get the form element. You can do it in many ways, use document.getElementById() or document.forms[], or $("#formid"). Whatever way you choose doesn't matter. Just note that a document can contain many forms, so you should reference a correct one. Getting form element by id returns an element that has an id attribute, getting it by the index in the forms property you should know the correct index. Once you get the form element you can reference input fields by name. For example
<form id="formid">
<input name="service">
</form>
<script>
var v = document.getElementById("formid")['service'];
</script>
Can you get the text() of a jxpath element or does it not work?
given some nice xml:
<?xml version="1.0" encoding="UTF-8"?>
<AXISWeb xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="AXISWeb.xsd">
<Action>
<Transaction>PingPOS</Transaction>
<PingPOS>
<PingStep>To POS</PingStep>
<PingDate>2012-11-15</PingDate>
<PingTime>16:35:57</PingTime>
</PingPOS>
<PingPOS>
<PingStep>POS.PROCESSOR18</PingStep>
<PingDate>2012-11-15</PingDate>
<PingTime>16:35:57</PingTime>
</PingPOS>
<PingPOS>
<PingStep>From POS</PingStep>
<PingDate>2012-11-15</PingDate>
<PingTime>16:35:57</PingTime>
</PingPOS>
</Action>
</AXISWeb>
//Does not work:
jxpc.getValue("/AXISWeb/Action/PingPOS[1]/PingStep/text()");
//Does not work:
jxpc.getValue("/action/pingPOS[1]/PingStep/text()");
//Does not work:
jxpc.getValue("/action/pingPOS[1]/PingStep[text()]");
I know I can get the text from using
jxpc.getValue("/action/pingPOS[1]/PingStep");
But that's not the point.
Shouldn't text() work? I could find no examples....
P.S. It's also very very picky about case and capitalization. Can you turn that off somehow?
Thanks,
-G
/AXISWeb/Action/PingPOS[1]/PingStep/text() is valid XPath for your document
But, from what I can see from the user guide of jxpath (note: I don't know jxpath at all), getValue() is already supposed to return the textual content of a node, so you don't need to use the XPath text() at all.
So you may use the following:
jxpc.getValue("/AXISWeb/Action/PingPOS[1]/PingStep");
Extracted from the user guide:
Consider the following XML document:
<?xml version="1.0" ?>
<address>
<street>Orchard Road</street>
</address>
With the same XPath, getValue("/address/street"), will return the string "Orchard Road", while
selectSingleNode("/address/street") - an object of type Element (DOM
or JDOM, depending on the type of parser used). The returned Element
is, of course, <street>Orchard Road</street>.
Now about case insensitive query on tag names, if you are using XPath 2 you can use lower-case() and node() but this is not really recommended, you may better use correct names.
/*[lower-case(node())='axisweb']/*[lower-case(node())='action']/...
or if using XPath 1, you may use translate() but it gets even worse:
/*[translate(node(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz') = 'axisweb']/*[translate(node(),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz') = 'action']/...
All in all, try to ensure that you use correct query, you know it is case sensitive, so it's better to pay attention to it. As you would do in Java, foo and fOo are not the same variables.
Edit:
As I said, XML and thus XPath is case sensitive, so pingStep cannot match PingStep, use the correct name to find it.
Concerning text(), it is part of XPath 1.0, there is no need for XPath 2 to use it. The JXPath getValue() is already doing the call to text() for you. If you want to do it yourself you will have to use selectSingleNode("//whatever/text()") that will returns an Object of type TextElement (depending on the underlying parser).
So to sum up, the method JXPathContext.getValue() already does the work to select the node's text content for you, so you don't need to do it yourself and explicitly call XPath's text().
From a post that I've anserwed before the method .getTextContent() do the job for you.
No need to use "text()" when you evaluate the Xpath.
Example :
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("D:\\Loic_Workspace\\Test2\\res\\test.xml"));
System.out.println(doc.getElementsByTagName("retCode").item(0).getTextContent());
If not, you will get the tag and the value. If you want do more take a look at this