org.w3c.dom.Document object in RFT - xpath

I am trying to use xpath in RFT. Searching over the net threw this code at me-
private static NodeList getNodesWithXPath(Document document, String xpathStr)
throws XPathExpressionException {
NodeList nodes = null;
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
if (xpathStr != null) {
XPathExpression expr = xpath.compile(xpathStr);
Object result = expr.evaluate(document, XPathConstants.NODESET);
nodes = (NodeList) result;
}
return nodes;
}
Now, I am new at RFT and totally at a loss about how to access the 'Document' object? Trying to typecast TestObject into this throws an exception. I could see a few examples stating something like
Document doc = parse(xmlFileLocation)
but I am not sure what this xmlFileLocation means. I have a simple web page where I need to identify the element using xpath.
P.S. - I understand there are other ways of identifying the object using atDescendant, etc, but I need to explicitly use xpath here due to some reasons.
Any help would be greatly appreciated.
Thanks!

They are different Document objects.
I think you got the code from IBM developerworks, and that is a document obtained from an XML file, thus browsable with XPATH.
RFT Document is com.rational.test.ft.object.interfaces.DocumentTestObject
while XML related one probably is org.w3c.dom.Document.
Totally different classes.
XPath is not supported by RFT and also no answers in the forums.
If you need XPath queries in your pages try something else, like Selenium.

Related

Is paging broken with spring data solr when using group fields?

I currently use the spring data solr library and implement its repository interfaces, I'm trying to add functionality to one of my custom queries that uses a Solr template with a SimpleQuery. it currently uses paging which appears to be working well, however, I want to use a Group field so sibling products are only counted once, at their first occurrence. I have set the group field on the query and it works well, however, it still seems to be using the un-grouped number of documents when constructing the page attributes.
is there a known work around for this?
the query syntax provides the following parameter for this purpose, but it would seem that Spring Data Solr isn’t taking advantage of it. &group.ngroups=true should return the number of groups in the result and thus give a correct page numbering.
any other info would be appreciated.
There are actually two ways to add this parameter.
Queries are converted to the solr format using QueryParsers, so it would be possible to register a modified one.
QueryParser modifiedParser = new DefaultQueryParser() {
#Override
protected void appendGroupByFields(SolrQuery solrQuery, List<Field> fields) {
super.appendGroupByFields(solrQuery, fields);
solrQuery.set(GroupParams.GROUP_TOTAL_COUNT, true);
}
};
solrTemplate.registerQueryParser(Query.class, modifiedParser);
Using a SolrCallback would be a less intrusive option:
final Query query = //...whatever query you have.
List<DomainType> result = solrTemplate.execute(new SolrCallback<List<DomainType>>() {
#Override
public List<DomainType> doInSolr(SolrServer solrServer) throws SolrServerException, IOException {
SolrQuery solrQuery = new QueryParsers().getForClass(query.getClass()).constructSolrQuery(query);
//add missing params
solrQuery.set(GroupParams.GROUP_TOTAL_COUNT, true);
return solrTemplate.convertQueryResponseToBeans(solrServer.query(solrQuery), DomainType.class);
}
});
Please feel free to open an issue.

Populating a dropdown list in Flash Builder

I'm currently using the following code in Flash Builder to return a list of variables from an XML file:
[Bindable] private var I_Authors:ArrayCollection = new ArrayCollection ();
private function init():void {
var param:Object = new Object();
param.action = "getAuthorXML";
authorService.send(param);
}
protected function authorService_resultHandler(event:ResultEvent):void
{
I_Authors = event.result.authors.author;
}
My problem is making use of this data in a dropdown list.
I have no trouble putting it into a data grid using dataProvider="{I_Authors}" and dataField="ID" etc., but all the attempts I've made to put a specific field (ID) into a dropdown list have resulted in "object Object".
I'm just starting out with flash builder so its probably a basic question but all of the tutorials I've followed on Adobe's website don't seem to be any help.
Would appreciate any advice.
Turns out you use labelField="" , just incase anyone else is a bit confused about this.
<s:DropDownList id="dropdownList" dataProvider="{________}" labelField="________"></s:DropDownList>
The problem is "author" is an object.
When you get your results from authorService you receive an object
I_Authors = event.result.authors.author;
So you have an array of objects.
You probably want to get property of your object eg.: author.ID
I_Authors = event.result.authors.author.ID;
So you have an array of author ID.
dataProvider= I_Authors
Let me know if it wasn't clear and you need more explanation.

Jersey and Odata Key Path Param format

I have a RESTful api using Jersey right now, and am converting it to be OData standard compliant. There are a few things I have not converted yet, but will get there, and is not important at this moment. One of the things I need to convert that is important is the key path params. Odata has the standard of making the key wrapped in parenthesis. So in this example myapi.com/product(1) - is the OData call to get a product whose id is 1. Currently that is possible in my system with this myapi.com/product/1
When I add the parenthesis to the path parameter I get a 404 error. My class level path is #Path("/product") and my method level path is #Path("({id})"), and use to be #Path("/{id}"). I've tried adding the parenthesis as part of the variable planning to strip them off in the method, and I've tried formatting the id with some regex #Path("{id : regex stuff}"), and neither works.
If I make my method path parameter like this #Path"/({id})") - so the call is myapi.com/product/(1), it works fine. The parenthesis is not the issue obviously. It seems the Jersey splits the uri into chunks using the forward slashes for the routing, and sense there is no forward slash between the id an root resource name, then nothing is found. It makes sense.
Is there a way to change Jerseys method of matching uri strings with some regex or something? Has anyone used Jersey with Odata? I would rather not use odata4j just for the resolution to this issue, it seems like there should be a way to get this to work.
What I did:
Based on Pavel Bucek's answer I did implement a ContainrRequestFilter independently to the filter I use for security. In my case I didn't look to see if existed, I just tried to do the replace.
try
{
String uriString = request.getRequestUri().toString();
uriString = uriString.replaceAll("(\(|\)\/?)", "/");
request.setUris(request.getBaseUri(), new URI(uriString));
} catch (final Exception e)
{
}
return request;
I think that the easiest way how to handle this "protocol" would be introducing ContainerRequestFilter, which would replace "()$" with "/$" in the incoming URI. So you will be able to serve OData and standard REST request in one app.
See http://jersey.java.net/nonav/apidocs/1.11/jersey/com/sun/jersey/spi/container/ContainerRequestFilter.html
Simple filter I used to test this case:
rc.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, new ContainerRequestFilter() {
#Override
public ContainerRequest filter(ContainerRequest request) {
try {
if(request.getRequestUri().toString().endsWith("(1)")) {
request.setUris(
request.getBaseUri(),
new URI(request.getRequestUri().toString().replace("(1)", "/1")));
}
} catch (Exception e) {
}
return request;
}
});
both
curl "http://localhost:9998/helloworld(1)"
curl "http://localhost:9998/helloworld/1"
hit same Resource method now. (Obviously you'll need to improve current filter to be able to handle various values, but it should work for you).

Does jsoup support xpath?

There's some work in progress related to adding xpath support to jsoup https://github.com/jhy/jsoup/pull/80.
Is it working?
How can I use it?
JSoup doesn't support XPath yet, but you may try XSoup - "Jsoup with XPath".
Here's an example quoted from the projects Github site (link):
#Test
public void testSelect() {
String html = "<html><div><a href='https://github.com'>github.com</a></div>" +
"<table><tr><td>a</td><td>b</td></tr></table></html>";
Document document = Jsoup.parse(html);
String result = Xsoup.compile("//a/#href").evaluate(document).get();
Assert.assertEquals("https://github.com", result);
List<String> list = Xsoup.compile("//tr/td/text()").evaluate(document).list();
Assert.assertEquals("a", list.get(0));
Assert.assertEquals("b", list.get(1));
}
There you'll also find a list of features and expressions of XPath that are supported by XSoup.
Not yet,but the project JsoupXpath has make it.For example,
String html = "<html><body><script>console.log('aaaaa')</script><div class='test'>some body</div><div class='xiao'>Two</div></body></html>";
JXDocument underTest = JXDocument.create(html);
String xpath = "//div[contains(#class,'xiao')]/text()";
JXNode node = underTest.selNOne(xpath);
Assert.assertEquals("Two",node.asString());
By the way,it supports the complete W3C XPATH 1.0 standard syntax.Such as
//ul[#class='subject-list']/li[./div/div/span[#class='pl']/num()>(1000+90*(2*50))][last()][1]/div/h2/allText()
//ul[#class='subject-list']/li[not(contains(self::li/div/div/span[#class='pl']//text(),'14582'))]/div/h2//text()
HtmlUnit supports XPath. I've used this for certain projects and it works reasonably well.

how to do validation with not well form XML while doing unmarshalling?

I have an unmarshaller along with an MySchema.xsd file.
StreamSource sources = new StreamSource(getClass().getClassLoader().getResourceAsStream("/xmlValidation.xsd"));
SchemaFactory sf = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );
unmarshaller.setSchema(sf.newSchema(sources));
And make a call to unmarshaller.setEventHandler() function, to specify a custom validation event handler, which basically format a error tips string , by:
final String errorString = new String();
unmarshaller.setEventHandler(new ValidationEventHandler() {
#Override
public boolean handleEvent(ValidationEvent validationevent) {
if(validationevent.getSeverity()!= ValidationEvent.WARNING){
errorString.format( "Line:Col[" + validationevent.getLocator().getLineNumber()
+ ":" + validationevent.getLocator().getColumnNumber()
+ "]:" + validationevent.getMessage());
return false;
}
return true;
}
});
The above codes seem work ok(I can get java object when the input string is validated. and also the error tips string is formated as excepted)
The problem is that, when the input xml is not well form, it also throw a SaxParseException.
Thanks in advance.
Andrew
Well formed relates to the XML syntax itself, as opposed to being valid WRT an XML schema:
http://en.wikipedia.org/wiki/Well-formed_element
If you have XML that is not well formed then you will get a ValidationEvent.FATAL_ERROR and unmarshalling will not be able to continue, as the underlying parser used by JAXB cannot continue.
For more information:
http://bdoughan.blogspot.com/2010/12/jaxb-and-marshalunmarshal-schema.html
K, I mess up something and get this problem.
Now I figure it out. If I am wrong, please point me out. below it's what I find in javadoc and test on my project:
javax.xml.bind.ValidationEventHandler can handler the constrain error with the given schema constrains, when unmarshaller is unmarshaling.
unmarshaller.unmarshal(xmlInputStream);
The ValidationEventHandler will be called during the unmarshaling process if error occurs.
The SAXEception will be thrown, if the xmlInputStream is not well form.
And I cant find a way to catch the SAXException, throw by the sax parser, so I guess using validation during unmarshaling can't due with un-well form xml string.
I use javax.xml.validation.Validator to validate that the xml string is well form and under constrain.
jaxbValidator.validate(xmlSource);
The above code will throw SAXException.
If no exception is thrown, then unmarshall the xml string into object.

Resources