#XmlElement(name = "Emp", type = UserBean.class)
#XmlElementWrapper(name = "Emps")
private List<UserBean> users;
if (users.stream().anyMatch(x -> x.getUsername().equals(userBean.getUsername()))
&& users.stream().anyMatch(x -> x.getPassowrd().equals(userBean.getPassowrd()))) {
login=true;
}
This function checks whether a password and name exist in a container. I fill the container from xml file. However, that only check that items are existing, not the matching.
xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Department>
<Emps>
<Emp>
<username>Name</username>
<password>name</password>
</Emp>
<Emp>
<username>Name2</username>
<password>name2</password>
</Emp>
</Emps>
</Department>
So I can enter username Name and the password name2 and login still will be true. Are they any ways to set login to true only if username and password are matching?
Just merge the conditions into a single predicate:
if (users.stream().anyMatch(x -> x.getUsername().equals(userBean.getUsername())
&& x.getPassowrd().equals(userBean.getPassowrd())))
Related
I am trying to query the value for location with the attribute tag in my xml below. How can I do so?
My current query only returns the value for the full attribute tag but I only want the value for location, which in this case is "sampleLocation"?
i.e: location="sampleLocation"
XML:
<Products>
<Product>
<name>Sample name</name>
<attribute id="sampleid" location="sampleLocation" type="sampleType"/>
</product>
</Products>
Current code:
public String getLocationByName(String name) {
final String nameToQueryFor = name;
return engine.new Query<String>(MY_COLLECTION) {
#Override
protected String query(Collection collection) throws Exception {
XQueryService service = queryService();
ResourceSet resourceSet = service.query(
format("//Products/Product[name='%s']" +
"/attribute"
, StringEscapeUtils.escapeXml(nameToQueryFor)
));
List<String> results = newArrayList();
for (String resource : new IterableStringResources(resourceSet)) {
results.add(resource);
}
return results.get(0);
}
}.execute();
}
[Edited for the 'location' + correction]
"//Products/Product/name[text()=%s]/next-sibling::attribute/attribute::location"
Translation: in the context of //Products/Product select the element <name> with a given text. Then take the next sibling element with the <attribute> type from which get the value of the location attribute (of this element)
Some examples of 'xpath location paths' straight from the horse's mouth.
My proposal is
//Product[child::name/text()={$nameToQueryFor}]/attribute/#location
This will only work when the variable is bound to a value for the element type
I was able to solve this using the following query:
"//Products/Product[name='%s']/attribute/#Location/string()"
which returns: "sampleLocation"
Note: without using the /string() at the end it was giving the error:
attribute 'Location' has no parent element
I have below xml in string object
<Emp>
<e1>
<x>ABC</x>
</e1>
<e2>
<x>XYZ</x>
</e2>
<e3>
<x>TTT</x>
</e3>
</Emp>
if i search string with "ABC" then i want to add test
so xml became
<Emp>
<e1>
<x>ABC</x>
<fail>test</fail>
</e1>
<e2>
<x>XYZ</x>
</e2>
<e3>
<x>TTT</x>
</e3>
</Emp>
if i search string with "XYZ" then i want to add test in e2
<Emp>
<e1>
<x>ABC</x>
</e1>
<e2>
<x>XYZ</x>
<fail>test</fail>
</e2>
<e3>
<x>TTT</x>
</e3>
</Emp>
Please let me know whow to use sub string here.
In order to get a List of elements Applicant from my database, I'm facing an issue when I try to retrieve them.
I know in this example that I'm fetching through a bad method : fetch on String ids of entities but this is subject to a refactor ;)
Here is my specification and the predicates loop with a join :
public static Specification<Applicant> applicantsMatchMobility(final String... mobilities) {
return new Specification<Applicant>() {
#Override
public Predicate toPredicate(Root<Applicant> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
Collection<Predicate> predicates = new ArrayList<>();
Join<Applicant, Mobility> applicantMobilityJoin = root.join("mobility");
for(String mobility : mobilities) {
predicates.add(builder.equal(applicantMobilityJoin.<Mobility>get("id"), Integer.parseInt(mobility)));
}
return builder.and(predicates.toArray(new Predicate[predicates.size()]));
}
};
}
It works fine when I pass only one id of Mobility entity but when it's a String ids array > 1 this returns always 0..
Here is my junit test :
#Test
public void ShouldHaveOneApplicantWhenSearchMobilityMultipleTotallyEquals(){
String mobilitiesId[] = {"0", "1"};
List<Applicant> applicantList = applicantRepository.findAll(applicantsMatchMobility(mobilitiesId));
Assert.assertNotNull(applicantList);
Assert.assertEquals("Result", 1, applicantList.size());
Applicant applicant = applicantList.get(0);
Assert.assertNotNull(applicant);
Assert.assertEquals("Result", "XBNC", applicant.getFirstName());
}
Here is the generated request from this :
select
*
from
applicant applicant0_
inner join
applicant_mobility mobility1_
on applicant0_.id=mobility1_.id_applicant
inner join
mobility mobility2_
on mobility1_.id_mobility=mobility2_.id
where
mobility2_.id=0
and mobility2_.id=1
Here is my dataset for testing :
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<MOBILITY ID="0" NAME="sud"/>
<MOBILITY ID="1" NAME="nice"/>
<MOBILITY ID="2" NAME="cannes"/>
<MOBILITY ID="3" NAME="nowhere"/>
<TAGS ID="0" NAME="tags1"/>
<TAGS ID="1" NAME="tags2"/>
<TAGS ID="2" NAME="tags3"/>
<STATUS ID="0" NAME="status1"/>
<STATUS ID="1" NAME="status2"/>
<AVAILABILITY ID="0" NAME="availability1"/>
<APPLICANT ID="0" LAST_NAME="XBNC" FIRST_NAME="XBNC" YEAR="2001" WAGE_CLAIM="50" ID_STATUS="0" ID_AVAILABILITY="0" />
<APPLICANT ID="1" LAST_NAME="XBN" FIRST_NAME="XBN" YEAR="0" WAGE_CLAIM="70" ID_STATUS="1" ID_AVAILABILITY="0"/>
<APPLICANT ID="2" LAST_NAME="MI" FIRST_NAME="MI" YEAR="1995" WAGE_CLAIM="0" ID_STATUS="1" ID_AVAILABILITY="0"/>
<APPLICANT ID="3" LAST_NAME="bisTronomique" FIRST_NAME="bisTronomique" YEAR="-400" WAGE_CLAIM="0" ID_STATUS="0" ID_AVAILABILITY="0"/>
<APPLICANT_MOBILITY ID_APPLICANT="0" ID_MOBILITY="0"/>
<APPLICANT_MOBILITY ID_APPLICANT="0" ID_MOBILITY="1"/>
<APPLICANT_MOBILITY ID_APPLICANT="1" ID_MOBILITY="0"/>
<APPLICANT_MOBILITY ID_APPLICANT="1" ID_MOBILITY="2"/>
<APPLICANT_MOBILITY ID_APPLICANT="2" ID_MOBILITY="1"/>
<APPLICANT_TAGS ID_APPLICANT="0" ID_TAGS="0"/>
<APPLICANT_TAGS ID_APPLICANT="0" ID_TAGS="1"/>
<APPLICANT_TAGS ID_APPLICANT="0" ID_TAGS="2"/>
</dataset>
Has you can see in this test I need to get back only the "XBNC" Applicant because he contains the 2 corresponding MobilityeID ..
This is a basic SQL logic problem, and I'm guessing you are trying to retrieve 2 rows corresponding to mobiliy IDs 0 and 1: the where clause (critria) in your current code builds [where id = '0' and id = '1'], which will always return no rows as a particular table field cannot be equal to two values at the same time.
Instead of and(), you need to use the or() method, which will build a where clause like [where id = '0' or id = '1']. Provided exactly one row and one row only has mobilityID set to 1, and one row and one row only has mobilityID set to 0, then you should obtain two rows back from running your query.
Update:
After your question edit, I think I can see your your issue lies. This is still a SQL problem, but it means your query need to be slightly more sophisticated. You need to obtain a query that looks like:
select
*
from
applicant applicant0_
inner join
applicant_mobility mobility1_
on applicant0_.id=mobility1_.id_applicant
inner join
mobility mobility2_
on mobility1_.id_mobility=mobility2_.id
where
exists (
select * from applicant_mobility
where id_applicant = applicant0_.id
and id_mobility = 1;
)
and
exists (
select * from applicant_mobility
where id_applicant = applicant0_.id
and id_mobility = 0;
)
Note the join between applicant and applicant_mobility in the sub-queries. This is effectively saying: for each applicant instance the main query finds, verify that it is in a set where there is at least one corresponding applicant_mobility instance with mobility set to 0, and another where mobility is set to 1.
So the loop in your function needs to create sub-queries per mobility id provided, and then use the builder and() and exists() to put it all together.
Add to what #NotSoOldNick has specified. What you seems to require is a IN Clause to retrieve only matching Applicant with matching Mobility. You can change it to the following or somewhat similar.
public static Specification<Applicant> applicantsMatchMobility(final String... mobilities) {
return new Specification<Applicant>() {
#Override
public Predicate toPredicate(Root<Applicant> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
Collection<Predicate> predicates = new ArrayList<>();
Join<Applicant, Mobility> applicantMobilityJoin = root.join("mobility");
Expression<String> idExp = applicantMobilityJoin.<Mobility>get("id");
return builder.and(idExp.in(mobilities));
}
};
}
I have a Maven and Spring based Java web application.
I have a config.xml file in src/main/resources.
<?xml version="1.0" encoding="UTF-8"?>
<sourceConfigs>
<areas>
<area name="Defects">
<fileHeaders>ID,Issue Key,Fields
</fileHeaders>
</area>
<area name="Organization">
<fileHeaders>ID,Org Key,Fields
</fileHeaders>
</area>
</areas>
<sourceTypes>
<source name="source1">
<adapterObject>source1Adapter</adapterObject>
<resultObject>JsonObject</resultObject>
</source>
<source name="source2">
<adapterObject>source2Adapter</adapterObject>
<resultObject>sourceObject</resultObject>
</source>
</sourceTypes>
</sourceConfigs>
I want to parse the above XML to Java object based on the attributes.
I have created two classes.
Area.java
#XmlRootElement(name="area")
public class Area {
String name;
String fileHeaders;
#XmlAttribute
//get Name
//set Name
#XmlElement
//get fileHeaders
//set FileHeaders
}
Source.java
#XmlRootElement(name="source")
public class Source {
String name;
String adapterObject;
String resultObject;
#XmlAttribute
//get Name
//set Name
#XmlElement
//get adapterObject
//set adapterObject
#XmlElement
//get resultObject
//set resultObject
}
I want to parse the XML based on the attribute value.
ie; if the attribute value of area is Defects, the parsed object should have the values based on that, else if its Organization, then the values based on that and object type to Area object. Similarly for Source type also.
How can I do that?
When it was only a simple XML file like following
<?xml version="1.0" encoding="UTF-8"?>
<sourceConfig area="Defects">
<adapterObject>jAdapter</adapterObject>
<resultObject>jsonObject</resultObject>
</sourceConfig>
My POJO was based on that and the code I used to parse is
public SourceConfig getConfigObject() throws JAXBException, IOException {
JAXBContext jaxbContext = JAXBContext.newInstance(SourceConfig.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Resource resource=new ClassPathResource("config.xml");
File file=resource.getFile();
SourceConfig sourceConfig = (SourceConfig) jaxbUnmarshaller.unmarshal(file);
return sourceConfig;
}
But for this complex I don't know how to parse based on attribute values, and also multiple list of data.
How to parse based on the attribute values?
I have created two POJOs for parsing different kind. If it's a single class also it's fine.
UPDATE 1
My expected output.
When I pass the value "Defects" when unmarshalling the Area object, The values should be
name= Defects
fileHeaders=ID,Issue Key,Fields
And If I pass "Organization", The area object values should be based on that. Similarly when unmarshalling source.
Now I am getting as List of Areas and List of SourceTypes, then I take the corresponding object by checking the value.
May be is there any way to parse only selected one based on attribute value instead of getting list and then checking value and returning the object?
Node existingUserNode = loginDoc.selectSingleNode("/returningUser");
String username = existingUserNode.selectSingleNode("/username").getText();
String password = existingUserNode.selectSingleNode("/password").getText();
for
<?xml version="1.0" encoding="UTF-8"?><returningUser><username>user</username><password>password</password></returningUser>
returns null.
I don't think my xpath is wrong? Or am I using the wrong method?
The syntax should be ./username and ./password... above I am looking one level too high by referencing the root
try this
Node existingUserNode = loginDoc.selectSingleNode("/returningUser");
String username = existingUserNode.selectSingleNode("/username").getNodeValue();
String password = existingUserNode.selectSingleNode("/password").getNodeValue();