My Scenario : I may get the different outputs which is shown below.I want to retrieve the "Units" tag value depends on Code tag.
Output1 :
<Riders>
<Rider>
<Name>ALSP</Name>
<Code>ALSP</Code>
<Units>3</Units>
</Rider>
<Rider>
<Name>Individual</Name>
<Code>Select Type of Coverage</Code>
<OptionCode>Individual</OptionCode>
<IsFeature>true</IsFeature>
</Rider>
</Riders>
Output2 :
<Riders>
<Rider>
<Name>AFO</Name>
<Code>AFO</Code>
<Units>6</Units>
</Rider>
<Rider>
<Name>Individual</Name>
<Code>Select Type of Coverage</Code>
<OptionCode>Individual</OptionCode>
<IsFeature>true</IsFeature>
</Rider>
</Riders>
I have tried below xpath but didn't worked out. Could anyone suggest me.
/Riders/Rider/Code[text()[contains(.,'AFO')] or text() [contains(.,'ALSP')]]/Units
Depending on if you want to get the node with regards to the root or just find any matching node, you could use something like...
*/Rider[Code[contains(.,'ALSP')]]/Units
Which will return you all the Units nodes which belong to any Rider node, which have a Code node, whose text contains ALSP
Of course you could also use...
*/Rider[Code[text() = 'ALSP']]/Units
If the Code must match exactly.
The above will find all the Units nodes of the Rider node anywhere in the document. If the position is important, you would need to replace */ with /Riders/ instead.
Now, if you want to find both ALSP and AFO, you could use something like...
*/Rider[Code[text() = 'ALSP' or text() = 'AFO']]/Units
Related
I have been playing around with the example number three in here http://jackrabbit.apache.org/jcr/first-hops.html , however to me it remains unclear how to get access to the properties of a node.
In the first screenshot
I used the debugger from my IDE and I evaluated this expression
session.getNode("/importxml/xhtml:html/xhtml:body/mathml:math/mathml:apply/mathml:apply[2]/mathml:apply[2]/mathml:cn").getProperty("jcr:xmltext/jcr:xmlcharacters").getString().trim();
You can see how I can get access to "jcr:xmltest/jcr:xmlcharacters" and have 2 as a result.
However, when I try to get this information, get this property out of the node, I am unable to perform this operation as in this screenshot.
This is the code fragment in the above screenshot:
var node = session.getNode("/importxml/xhtml:html/xhtml:body/mathml:math/mathml:apply/mathml:apply[2]/mathml:apply[2]/mathml:cn");
var properties = node.getProperties();
List<string> result = new ArrayList<>();
while(properties.hasNext()) {
Property property = properties.nextProperty();
result.add(property.getString().trim());
}
return result;
You can see how I get as a response only a value containing "nt:unstructured".
Unfortunately I couldn't find many code examples online, on Github, etc. many outdated, and also, there are not books as there are for Scrapy or other libraries/frameworks.
Thank you in advance.
Have a nice day!
Davide
In the first case, you are looking at the properties of:
/importxml/xhtml:html/xhtml:body/mathml:math/mathml:apply/mathml:apply[2]/mathml:apply[2]/mathml:cn/jcr:xmltext
In the second case:
/importxml/xhtml:html/xhtml:body/mathml:math/mathml:apply/mathml:apply[2]/mathml:apply[2]/mathml:cn
Note the different paths.
How to retrieve all nested classes of parent class ?
I wants to get name of class (toast toast-success & toast-message). I can have stable id=toast-container but its nested class can be change. so need to retrieve all classes of toast-container.
You can do this by using xpath. There are several ways to do this, here are two examples. I use C#, but that doesn't change the xpaths. My camel casing might be off though for java.
Example 1:
var elements = driver.findElements(by.xpath("//div[#id='toast-container']//*"));
This will give you all elements within the div with id toast-container.
Example 2:
var el = driver.findElement(by.id("toast-container"));
var elements = el.findElements(by.xpath("//*"));
The seconds example does the same as the first, but you create the toast-container element first so you can do whatever you want with it from that point on.
Once you have your list of elements, make a foreach loop and check the class names. So you can say:
foreach(WebElement element in elements)
{
try{
var className = element.getAttribute("class");
}
catch(Exception e)
{
//do whatever you want to do with elements which have no class in them
}
}
The easiest way to do this would be to just get the outerHTML of the parent element.
String html = driver.findElement(By.id("toast-container")).getAttribute("outerHTML");
That will dump all the HTML of the parent and children. From there you can get whatever you want. I'm assuming you don't just want the classes but would like to know what all elements exist and what classes are on which elements.
So I have the following input, expected output and actual output xml:
input.xml
<Request>
<EmailSubjectLine>Main Contact & No Reported To</EmailSubjectLine>
<ProductRq>
<Signon>
<ClientDt>1/6/2017 11:25:45 AM</ClientDt>
<CustLangPref>en-US</CustLangPref>
</Signon>
<SvcRq>
<RqUID>xxxxxxxx-2802-xxxx-xxxx-bf8361xxxxxx</RqUID>
<NotificationRq>
<TransactionRequestDt>2017-01-06</TransactionRequestDt>
<Currency>USD</Currency>
</NotificationRq>
</SvcRq>
</ProductRq>
<!-- rest of input -->
</Request>
expected-output.xml
<ProductRq xmlns="http://test.org/standards/intake">
<Audit>
<TransID>Test</TransID>
</Audit>
<Signon>
<ClientDt>1/6/2017 11:25:45 AM</ClientDt>
<CustLangPref>en-US</CustLangPref>
</Signon>
<SvcRq>
<RqUID>xxxxxxxx-2802-xxxx-xxxx-bf8361xxxxxx</RqUID>
<NotificationRq>
<RqUID>Test</RqUID>
<TransactionRequestDt>2017-01-06</TransactionRequestDt>
<Currency>USD</Currency>
</NotificationRq>
</SvcRq>
<!-- rest of expected-output -->
</ProductRq>
actual-output.xml
<ProductRq xmlns="http://test.org/standards/intake">
<Audit>
<TransID>123534Abwe-asdcv-1258qw-asd</TransID>
</Audit>
<Signon>
<ClientDt>1/6/2017 11:25:45 AM</ClientDt>
<CustLangPref>en-US</CustLangPref>
</Signon>
<SvcRq>
<RqUID>xxxxxxxx-2802-xxxx-xxxx-bf8361xxxxxx</RqUID>
<NotificationRq>
<RqUID>CG-17Dawe-12354-Hw35Sf</RqUID>
<TransactionRequestDt>2017-01-06</TransactionRequestDt>
<Currency>USD</Currency>
</NotificationRq>
</SvcRq>
<!-- rest of actual-output -->
</ProductRq>
I'm comparing them with the following Diff set up:
MyTest.java
Diff diff = DiffBuilder
.compare(xmlExpectedOutput)
.withTest(xmlOutput)
.normalizeWhitespace()
.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
.whenElementIsNamed("Audit")
.thenUse(ElementSelectors.byXPath("./TransID", ElementSelectors.byName))
.whenElementIsNamed("NotificationRq")
.thenUse(ElementSelectors.byXPath("./RqUID", ElementSelectors.byName))
.elseUse(ElementSelectors.byNameAndText)
.build()
))
.checkForSimilar()
.build();
I get the following differences when I run the above input and compare with expected-output.xml:
[Expected child '{http://test.org/standards/intake}RqUID' but was 'null' - comparing <RqUID...> at /ProductRq[1]/SvcRq[1]/NotificationRq[1]/RqUID[1] to <NULL> (DIFFERENT), Expected child 'null' but was '{http://test.org/standards/intake}RqUID' - comparing <NULL> to <RqUID...> at /ProductRq[1]/SvcRq[1]/NotificationRq[1]/RqUID[1] (DIFFERENT)]
I don't get why my Element selector wouldn't work, am I using it incorrectly? My aim is whenever TransmissionId or NotificationRq/RqUID are found, to match them with the expected output versions by name only, otherwise use name and text for other elements as these elements contain unique generated ids that change every test run and can't be predicted(with a view to creating a more complex selector later, e.g. to compare ProductRq via name and attribute as a namespace is added to this). Is there something I'm missing, and am I able to combine the 2 XPath selectors together rather than several when/then lines and the default case?
Note: the xml is transformed via xslt. The namespace on PRoductRq is not there on the source document; the source is copied, the namespace added to ProductRq and then sent for output along with some element removals/modifications/additions
XMLUnit says the RqUID elements inside the NotificationRq wouldn't match and of course they are different.
.whenElementIsNamed("NotificationRq")
.thenUse(ElementSelectors.byXPath("./RqUID", ElementSelectors.byName))
means: when XMLUnit tries to find a partner for an NotificationRq element then it has to search for an NotificationRq that has an RqUID child - and only use the RqUID element.
It doesn't set up any rules for any other element, in particular RqUID itself. For RqUID elements the default rules apply and
.elseUse(ElementSelectors.byNameAndText)
says: XMLUnit only accepts two elements as pairs if their names and the nested text match. Which is not the case for the RqUID elements in question.
Your whole ElementSelector says
match Audits if they have TransID children of arbitrary content.
match NotificationRqs if they have RqUID of arbitrary content.
use element name and nested text otherwise
which doesn't fit your example. Looking at your XML you probably wanted
match almost everything by element name and nested text (although from the example the element name would be enough)
ignore the nested text of TransId children of Audits
ignore the nested text of RqUID children of NotificationRq
There is no built-in predicate for "element named foo if it is a child of an element named bar", it could be something like
Predicate<Element> transIdInAudit = e -> {
if (e == null || e.getParentNode() == null) {
return false;
}
return "TransID".equals(e.getLocalName()) && "Audit".equals(e.getParentNode().getLocalName());
};
which you likely want to make generalizable :-)
With that you'd use
.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
.when(transIdInAudit)
.thenUse(ElementSelectors.byName)
.when(rqUIDInNotificationRq) // similar to transIdInAudit
.thenUse(ElementSelectors.byName)
.elseUse(ElementSelectors.byNameAndText)
.build())
Maybe you really want to match SvcRq if they have matching RqUID, maybe not. If so you'd use the structure you currently use for NotificationRq.
This in itself will not be enough to ignore the nested text of the matched TransId and RqUID elements, it will only ensure XMLUnit will pick the nodes you want it to use. For the nested text you'll need a DifferenceEvaluator.
Given that you are using ElementSelectors.byNameAndText by default, you know the nested texts are the same for all matched nodes except for the two specific elements where you want to ignore the content. So a DifferenceEvaluator like
DifferenceEvaluators.chain(DifferenceEvaluators.Default,
DifferenceEvaluators.downgradeDifferencesToEqual(ComparisonType.TEXT_VALUE))
should work.
I've been trying to create an XML document in Java using DOM where there are multiple car elements of the same name on the same hierarchical level, similar to the following:
<Root>
<Car>
<Make>Ford</Make>
<Model>Fiesta</Model>
</Car>
<Car>
<Make>VW</Make>
<Model>Golf</Model>
</Car>
</Root>
However, during construction of the XML, whenever I attempt to add another Car element, it seems to override the one that is already there, resulting in me only getting one Car element in my output.
I create the car element using the following code:
Element carElement = doc.createElement("Car");
And then attempt to append to the first Car element that I create using the following code:
root.appendChild(carElement);
I have also tried the following code to no avail:
Node existingCar = doc.getElementsByTagName("Car").item(0);
existingCar.getParentNode().insertBefore(carElement, existingCar);
The Java docs state that for both the appendChild() and insertBefore() methods, if the newChild node exists, then it will firstly be removed - hence why I think Im only seeing one output in my XML.
Therefore, can someone confirm whether or not this is possible with DOM? If so, can they please advise or point me in the direction of a solution? Thanks
I can confirm that this is possible with DOM!
You haven't shown us your actual code where you try to add more than one child element with the same name, so we cannot tell you exactly why it doesn't work. However, maybe this snippet will give you a hint of how to fix your code. To add five Carelements:
DocumentBuilder b = ...;
DOMImplementation impl = b.getDOMImplementation();
Document d = impl.createDocument(null, "Root", (DocumentType) null);
Element root = d.getDocumentElement();
for (int i = 0; i < 5; ++i) {
Element car = d.createElement("Car");
// add sub-elements/attributes to car element
...
root.appendChild(car);
}
Okay, to clarify, I have an XML/RDF file that describes data with a natural categorical tree structure (like folders and files). The data is not structured in a tree, rather, there is information that explains how to rebuild the tree (namely the nested set values of each node). I am starting with no knowledge other than the assumption that some statement in the file has a RootTree property who's object is the URI of the statement describing the root node of the tree.
Obtaining that object is easy, I simply use:
// Obtain the node describing the root of the Pearltree.
mRootProp = mModel.createProperty(Pearltree.RDF.PearlTreeNS, "rootTree");
NodeIterator roots = mModel.listObjectsOfProperty(mRootProp);
Now, I am further able to list all statements which have the property pt:parentTree and the object roots.nextNode():
StmtIterator sit = mModel.listStatements(null, RDF.ParentTree, rootNode);
This gives me a list of all such statements. These statements are part of elements that look like such in the RDF/XML file (note these have a different parentTree value but appear in the same context):
<pt:RootPearl rdf:about="http://www.pearltrees.com/dcow/pearltrees-videos/id5296268#rootPearl">
<dcterms:title><![CDATA[Pearltrees videos]]></dcterms:title>
<pt:parentTree rdf:resource="http://www.pearltrees.com/dcow/pearltrees-videos/id5296268" />
<pt:inTreeSinceDate>2012-06-11T20:25:55</pt:inTreeSinceDate>
<pt:leftPos>1</pt:leftPos>
<pt:rightPos>8</pt:rightPos>
</pt:RootPearl>
<pt:PagePearl rdf:about="http://www.pearltrees.com/dcow/pearltrees-videos/id5296268#pearl46838293">
<dcterms:title><![CDATA[why Pearltrees?]]></dcterms:title>
<dcterms:identifier>http://www.youtube.com/watch?v%3di4rDqMMFx8g</dcterms:identifier>
<pt:parentTree rdf:resource="http://www.pearltrees.com/dcow/pearltrees-videos/id5296268" />
<pt:inTreeSinceDate>2012-06-11T20:25:55</pt:inTreeSinceDate>
<pt:leftPos>2</pt:leftPos>
<pt:rightPos>3</pt:rightPos>
</pt:PagePearl>
...
Now, what I would like to do is obtain a reference to all statements with subject sit.nextStatement()'s subject. In this example:
"http://www.pearltrees.com/dcow/pearltrees-videos/id5296268#rootPearl"
and
"http://www.pearltrees.com/dcow/pearltrees-videos/id5296268#pearl46838293"
My goal is to obtain the content of each element including its rightPos and leftPos so I can reconstruct the tree.
You can simplify your code somewhat as follows:
mRootProp = mModel.createProperty(Pearltree.RDF.PearlTreeNS, "rootTree");
Resource root = mModel.listResourcesWithProperty( mRootProp ).next();
This assumes you know you have exactly one root per model. If that might not be true, modify the code accordingly.
The method:
getSubject()
of a Statement will return the Subject as a Resource. You can then use the
getProperty(Property p)
method of the returned Resource to obtain the Statements that include the property in question.
So, in my case, I use:
Resource r;
Statement title, id, lpos, rpos;
while(sit.hasNext()) {
r = sit.nextStatement().getSubject();
title = r.getProperty(DCTerms.title);
id = r.getProperty(DCTerms.identifier);
lpos = r.getProperty(PearlTree.RDF.leftPos);
rpos = r.getProperty(PearlTree.RDF.rightPos);
...
}