XPath expressions? - xpath

<?xml version="1.0" encoding="UTF-8"?>
<Patients>
<patientRole>
<id extension="996-756-495" root="2.16.840.1.113883.19.5"/>
<id extension="775-756-495" root="2.16.840.1.113883.14.6"/>
<patient>
<name>
<given>Henry</given>
<family>Levin</family>
</name>
<administrativeGenderCode code="M" codeSystem="2.16.840.1.113883.5.1"/>
<birthTime value="19320924"/>
</patient>
<providerOrganization>
<id root="2.16.840.1.113883.19.5"/>
<name>Good Health Clinic</name>
</providerOrganization>
<admissionTime value="2012030111:32"/>
</patientRole>
<patientRole>
<id extension="65" root="2.16.840.1.113883.3.933"/>
<patient>
<name>
<given>Paul</given>
<family>Pappel</family>
</name>
<administrativeGenderCode code="M" codeSystem="2.16.840.1.113883.5.1"/>
<birthTime value="19551217"/>
</patient>
<providerOrganization>
<id extension="84756-11241-283-OPTD-3322" root="1.2.3.4.5.6.1.8.9.0"/>
<name> Dr.med. Hans Topp-Glucklich</name>
</providerOrganization>
<admissionTime value="201201152200"/>
</patientRole>
<patientRole>
<id extension="800001" root="2.16.840.1.113883.19.5"/>
<patient>
<name>
<given>JEANNE</given>
<family>PETIT</family>
</name>
<administrativeGenderCode code="F" codeSystem="2.16.840.1.113883.5.1"/>
<birthTime value="19480105"/>
</patient>
<providerOrganization>
<id root="2.16.840.1.113883.19.5"/>
<name>Good Health Clinic</name>
</providerOrganization>
<admissionTime value="20120101T22:00"/>
</patientRole>
</Patients>
I am having difficulty writing XPath expressions for the following two items:
Given and family name of the patient born on 17 Dec 1955
Number of patients admitted to "Good Health Clinic" in January 2012

This will get you the name element of the patients born on the particular date:
patientRole/patient[birthTime/#value="19551217"]/name
This will get you the count of patientRole elements with the organisation name and admission date specified:
count(patientRole[providerOrganization/name="Good Health Clinic"][starts-with(admissionTime/#value,"201201")])

Related

Can't index data in alphabetical order in spanish alphabet before to select it in a query

I have a set of assets which had a property "name".
I want to get a dynamic number of those assets and I should get it alphabetically sorted by that "name" property.
I query that with this query:
type=dam:Asset
path=/content/dam/en/foobar/contacts/
orderby=#jcr:content/data/master/#name
orderby.sort=asc
p.limit=3
and this is working, so in a set of names:
[Paloma, Abel, José, Eduardo]
it retrieves:
Abel, Eduardo, José.
The problem is with spanish alphabet, in which Á is the same letter as A.
So in a set of:
[Paloma, Abel, José, Álvaro, Eduardo]
it retrieves:
Abel, Eduardo, José.
Being Álvaro excluded because its not part of the first 3 elements after ordeby it, when in should be the second, it should retrieve:
Abel, Álvaro, Eduardo.
So, to fix that, I've created a custom oak lucene index like below:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:oak="http://jackrabbit.apache.org/oak/ns/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:rep="internal"
jcr:mixinTypes="[rep:AccessControllable]"
jcr:primaryType="nt:unstructured">
<socialLucene/>
<workflowDataLucene/>
<slingeventJob/>
<jcrLanguage/>
<versionStoreIndex/>
<repMembers/>
<cqReportsLucene/>
<commerceLucene/>
<counter/>
<authorizables/>
<enablementResourceName/>
<externalPrincipalNames/>
<cmLucene/>
<foobarCFIndexFilter
jcr:primaryType="oak:QueryIndexDefinition"
async="[async,nrt]"
evaluatePathRestrictions="{Boolean}true"
includedPaths="[/content/dam/es/foobar,/content/dam/en/foobar]"
queryPaths="[/content/dam/es/foobar,/content/dam/en/foobar]"
reindex="{Boolean}false"
reindexCount="{Long}24"
seed="{Long}3850652403740003290"
type="lucene">
<analyzers jcr:primaryType="nt:unstructured">
<default jcr:primaryType="nt:unstructured">
<filters jcr:primaryType="nt:unstructured">
<Synonym
jcr:primaryType="nt:unstructured"
format="solr"
synonyms="synonyms.txt">
<synonyms.txt/>
</Synonym>
</filters>
<tokenizer
jcr:primaryType="nt:unstructured"
name="Classic"/>
</default>
</analyzers>
<indexRules jcr:primaryType="nt:unstructured">
<nt:base jcr:primaryType="nt:unstructured">
<properties jcr:primaryType="nt:unstructured">
<title
jcr:primaryType="nt:unstructured"
analyzed="{Boolean}true"
isRegexp="{Boolean}false"
name="jcr:content/data/master/title"
nodeScopeIndex="{Boolean}true"
ordered="{Boolean}true"
propertyIndex="{Boolean}true"
type="String"/>
<date
jcr:primaryType="nt:unstructured"
name="jcr:content/data/master/date"
ordered="{Boolean}true"
propertyIndex="{Boolean}true"/>
<sectors
jcr:primaryType="nt:unstructured"
name="jcr:content/data/master/sectors"
propertyIndex="{Boolean}true"/>
<contentFragment
jcr:primaryType="nt:unstructured"
name="jcr:content/contentFragment"
propertyIndex="{Boolean}true"/>
<model
jcr:primaryType="nt:unstructured"
name="cq:model"
propertyIndex="{Boolean}true"/>
<name
jcr:primaryType="nt:unstructured"
analyzed="{Boolean}true"
isRegexp="{Boolean}false"
name="jcr:content/data/master/name"
nodeScopeIndex="{Boolean}true"
ordered="{Boolean}true"
propertyIndex="{Boolean}true"
type="String"/>
</properties>
</nt:base>
</indexRules>
</foobarCFIndexFilter>
<cqProjectLucene/>
<ntFolderDamLucene/>
<acPrincipalName/>
<uuid/>
<damAssetLucene/>
<rep:policy/>
<cqPayloadPath/>
<nodetypeLucene/>
<nodetype/>
<ntBaseLucene/>
<reference/>
<principalName/>
<cqTagLucene/>
<lucene/>
<repTokenIndex/>
<externalId/>
<authorizableId/>
<cqPageLucene/>
</jcr:root>
Where in the synonyms.txt I had:
á, a
Á, A
and so on.
Also tried with a charFilter with Mapping equivalent chars.
I have made sure that my custom oak index is the one my query is using with Query Performance Diagnosis tool.
But nothing works, after reindex the query results are the same.
How to solve that?

Selecting Value of Sibling Node When Node = X

When looking at this XML tree:
<ids>
<id>
<id>1</id>
<qty>0.0000</qty>
</id>
<id>
<id>2</id>
<qty>0.0000</qty>
</id>
<id>
<id>3</id>
<qty>0.0000</qty>
</id>
<id>
<id>4</id>
<qty>10.0000</qty>
</id>
<id>
<id>5</id>
<qty>0.0000</qty>
</id>
</ids>
How would one go about choosing the qty with a sibling id of 4?
So far I've tried:
<xsl:value-of select="ids/id[id = '4']/qty"/>
<xsl:value-of select="ids/id/qty[../id = '4']"/>
However, the only result that is ever returned is qty = 0.0000.
Try this XPath-1.0 expression:
/ids/id[id='4']/qty

XSLT: filter and retrieve different elements

<cars>
<car>
<name v="speedy"/>
<type v="sport"/>
<engine>
<hp>300</hp>
</engine>
<car>
<car>
<name v="biggo"/>
<type v="truck"/>
<engine>
<hp>190</hp>
</engine>
<car>
</cars>
I have a problem in building a xpath-term that gives my biggos horsepower.
I am not sure how to filter and get the value of something that is not in the filtered element.

XPATH get default value when node is empty or not present

I have 3 types of data
<results>
<place>
<key>place</key>
<value>1</value>
</place>
</results>
OR
<results>
<place>
<key>place</key> // notice the missing value
</place>
</results>
OR
<results>
</results>
So my sample data will be like
<event>
<results>
<place>
<key>place</key>
<value>1</value>
</place>
<some additional data here>
</results>
</event>
<event>
<results>
<place>
<key>place</key>
</place>
<some additional data here>
</results>
</event>
<event>
<results>
<some additional data here>
</results>
</event>
I need an XPath expression that can give me a default value when <value> of <place> is present, null or missing. <place> can be missing as well in some cases as mentioned in my third sample data.
Output that I expect here is 1, <default-value>, <default-value>.
XPATH 2.0 solution will work as well. I have tried scourging stackoverflow and google but couldnt find anything.
Use:
//results/concat(place/value, for $r in . return 'default-value'[not($r/place/value)])
XSLT - based verification:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:sequence select=
"//results/concat(place/value, for $r in . return 'default-value'[not($r/place/value)])"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided (and completed) XML document:
<t>
<event>
<results>
<place>
<key>place</key>
<value>1</value>
</place>
<x/>
</results>
</event>
<event>
<results>
<place>
<key>place</key>
</place>
<y/>
</results>
</event>
<event>
<results>
<z/>
</results>
</event>
</t>
the XPath expression is evaluated and its results are copied to the output:
1 default-value default-value
I did it finally after a lot of trial and error.
{xpath::/events/event/(results//(place|rank)/value/string(), '')[1]}
the trick was to go one level up i.e. <results> in my case and then use the (if value present, default-value) XPATH notation.
Earlier, I was trying this unsuccessfully.
{xpath::/events/event/results//((place|rank)/value/string(), '')[1]}

How to write a Xpath Expression comparing two attributes or nodes

Given the following sample:
<?xml version="1.0" encoding="UTF-8"?>
<Patients>
<patientRole>
<id extension="996-756-495" root="2.16.840.1.113883.19.5"/>
<id extension="775-756-495" root="2.16.840.1.113883.14.6"/>
<patient>
<name>
<given>Henry</given>
<family>Levin</family>
</name>
<administrativeGenderCode code="M" codeSystem="2.16.840.1.113883.5.1"/>
<birthTime value="19320924"/>
</patient>
<providerOrganization>
<id root="2.16.840.1.113883.19.5"/>
<name>Good Health Clinic</name>
</providerOrganization>
<admissionTime value="2012030111:32"/>
</patientRole>
<patientRole>
<id extension="65" root="2.16.840.1.113883.3.933"/>
<patient>
<name>
<given>Paul</given>
<family>Pappel</family>
</name>
<administrativeGenderCode code="M" codeSystem="2.16.840.1.113883.5.1"/>
<birthTime value="19551217"/>
</patient>
<providerOrganization>
<id extension="84756-11241-283-OPTD-3322" root="1.2.3.4.5.6.1.8.9.0"/>
<name> Dr.med. Hans Topp-Glucklich</name>
</providerOrganization>
<admissionTime value="201201152200"/>
</patientRole>
<patientRole>
<id extension="800001" root="2.16.840.1.113883.19.5"/>
<patient>
<name>
<given>JEANNE</given>
<family>PETIT</family>
</name>
<administrativeGenderCode code="F" codeSystem="2.16.840.1.113883.5.1"/>
<birthTime value="19480105"/>
</patient>
<providerOrganization>
<id root="2.16.840.1.113883.19.5"/>
<name>Good Health Clinic</name>
</providerOrganization>
<admissionTime value="20120101T22:00"/>
</patientRole>
</Patients>
How would I write a X-Path expression for the following:
Family names for the male patients (gender code="M")
Any help is greatly appreciated I am new to XML/Xpath and i have tried multiple ways and its not generating what i need.
This should work:
/Patients/patientRole/patient[administrativeGenderCode/#code='M']/name/family

Resources