Getting attribute with condition using XPath - xpath

I am using iReport 5.6.0 to generate a report with xml datasource .
I need to select the attribute date of a node that have an attribute named Type with a value of START
Since I'm new to iReport and XPath , i can't find the right XPath query .
I've tried this , but it didn't work :
<!-- language: lang-xml -->
<queryString language="xPath">
<![CDATA[/Document]]>
</queryString>
<field name="Date" class="java.lang.String">
<fieldDescription>
<![CDATA[Date/#Date[#type="START"]]]>
</fieldDescription>
</field>
Here 's my XML data file :
<!-- language: lang-xml -->
<?xml version='1.0' encoding="UTF-8"?>
<Document>
<Date Type="INV" Date="20140601" />
<Date Type="START" Date="20140201" />
</Document>
(I need the value : 20140201 to be displayed)

This is the XPath expression you're looking for:
Date[#Type="START"]/#Date
In natural language: get the Date attribute from Date elements that have a Type attribute with value "START".

Related

Get XML attribute value of property using XPath

I have a XML like the example below:
<?xml version="1.0" encoding="UTF-8" ?>
<testsuite errors="0" failures="0" name="test" tests="1" time="2.747">
<properties>
<property name="categories" value="ExampleCategory" />
<property name="timestamp" value="1519664414463" />
</properties>
<testcase classname="com.example.junit.Test" name="test" time="2.747" />
</testsuite>
Is there a way to retrieve the property tag value according to the name of the property?
Right now, I'm using something like that:
#doc.xpath('//testsuite//properties//property/#value').text
This will give me "ExampleCategory1519664414463".
I know if I use .first or [0], [1], etc, I can get the values separately, but I couldn't find a way to get the values separately according to the "name" attribute.
Anyone know how can I retrieve that?
This XPath,
//property[#name='timestamp']/#value
will select all value attributes of property elements with a name attribute value equal to 'timestamp'.

What's the difference between <filled> tag inside the <field> tag and out of it?

The <filled> tag can be written under <field> tag and also outside of the tag, under the a <form> tag.
So what's the difference between these two way of writing code?
And In which scenario this will be beneficial?
Example can be found in : http://help.voxeo.com/go/help/xml.vxml.tutorials.audio
If you write tag inside then it will be a particular handling for that tag.
If you write outside then it can be used for like multiple inputs manipulation that is caught under .
eg.
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.1" xmlns="http://www.w3.org/2001/vxml">
<form id="get_starting_and_ending_cities">
<field name="start_city">
<grammar src="city.grxml"
type="application/srgs+xml"/>
<prompt>What is the starting city?</prompt>
</field>
<field name="end_city">
<grammar src="city.grxml"
type="application/srgs+xml"/>
<prompt>What is the ending city?</prompt>
</field>
<filled mode="all" namelist="start_city end_city">
<log><value expr="start_city"/></log>
<log><value expr="end_city"/></log>
<if cond="start_city == end_city">
<prompt>
You can't fly from and to the same city.
</prompt>
</if>
</filled>
</form>
</vxml>

Spring Integration Xpath Filter with Regex

I am using an Xpath Filter to filter out some incoming events.
This is my sample input xml. I need to filter by the value of fieldC, by allowing events that have a fieldC value of 1,2,3,6 or 7.
<?xml version="1.0" encoding="UTF-8"?>
<add>
<doc>
<field name="fieldA">453.97</field>
<field name="fieldB">278.25</field>
<field name="fieldC">3</field>
<field name="fieldD">Agent</field>
<field name="fieldE">Mobile Site</field>
<field name="fieldF">Cancel</field>
<field name="fieldG">2015-09-14T13:17:21.000Z</field>
</doc>
</add>
Xpath Tried:
/add/doc/field[#name='fieldC']/text()
/add/doc/field[#name='fieldC']
<int:chain input-channel="channelIn" output-channel="channelOut">
<int-xml:xpath-filter id="filterEvents" match-value="3" match-type="exact">
<int-xml:xpath-expression expression="/add/doc/field[#name='fieldC']/text()" />
</int-xml:xpath-filter>
</int-xml:xpath-filter>
</int:chain>
Filter by match-type 'exact' works, but I am not able to get the same working with regex.
Regex Tried: /^(1|2|3|6|7)$/
Any help would be appreciated.
Your regex has bad syntax; lose the /s...
match-value="^(1|2|3|6|7)$" match-type="regex"
...works fine for me.

How to show currency symbol instead of currency name?

I created a module to show related Purchase Orders from projects:
After clicking the Compras (Purchases) button a custom tree view is shown with the currency_id field:
Is there a way to show the symbol of the currency instead of the name? Something like you would do for example using Django: currency_id.symbol. Even better, I want to drop the currency_id field and prepend the currency symbol in the total amount, is that possible? Something like S/. 336.30 in the amount_total field.
Here's my tree view:
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
....
....
<record id="purchase_order_project_tree" model="ir.ui.view">
<field name="name">purchase.order.tree</field>
<field name="model">purchase.order</field>
<field name="arch" type="xml">
<tree string="Compras"
colors="grey:state=='cancel';blue:state in ('wait','confirmed');red:state in ('except_invoice','except_picking')">
<field name="name" string="Reference"/>
<field name="date_order" />
<field name="partner_id"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
<field name="currency_id" />
<field name="amount_total" />
<field name="state"/>
</tree>
</field>
</record>
....
....
</data>
</openerp>
You can add a field called currency_symbol in your module (py) that gets the currency symbol when the currency changues with an on_changue to the currency. So you bring that field to the view, you cant directly do it from the XML.
When you click on the that button to get the tree get listed, you can override the "name_get" method of "Currency" and fetch the "currency symbol" instead of name. For this you can pass a flag in the context to limit this modification specific to your module only.
Hope this helps!!.

Working With Nested XPath Predicates ... Refined

All great answers! But the question deserves refinement ...
I've got the following sample XML ...
<objects>
<object objectId="1123" ... />
<properties refObjectId="1123" ... />
<properties refObjectId="1123" refPropertyId="2311" ... />
<properties refObjectId="1123" refPropertyId="4611" ... />
<object objectId="2123" ... />
<properties refObjectId="2123" refPropertyId="4311" ... />
<properties refObjectId="2123" refPropertyId="8611" ... />
....
</objects>
... and the following XPath query ...
//object[//properties[#refObjectId=#objectId and not(#refPropertyId)]]
I thought this query would return all object nodes where there is a properties node that has a refObjectId attribute that equals the objectId attribute of the object node and no 'refPropertyId' attribute ... namely object 1123 only, not object 2123 ... but it doesn't. It seems the #objectId in the nested predicate does not refer to the objectId attribute of the object node.
Any ideas? I know the XML structure isn't nested as you would expect, but there are reasons for this structure.
Generally you should avoid using // where you can. I'd consider rephrasing:
//object[../properties/#refObjectId=#objectId]
In the expression provided, your nested predicate is actually checking for
//properties/#refObjectId=//properties/#objectId
of which there are none.
I hope this helps!
EDIT: Since the question has been updated here is an updated response:
You added "It seems the #objectId in the nested predicate does not refer to the objectId attribute of the object node." You're absolutely right! So let's fix it!!
//object[../properties[not(#refPropertyId)]/#refObjectId=#objectId]
This should be closer to what you're after!
Try this:
//objects[object/#objectId = properties/#refObjectId]/object
This should work:
//objects/object[#objectId = ../properties/#refObjectId]
I am not sure how your xml is. However, if it is in the following format:
<objects>
<object objectId="1111" />
<properties refObjectId="1111" />
<object objectId="2111" />
<properties refObjectId="3111" />
<object objectId="4111" />
<properties refObjectId="5111" />
<object objectId="6111" />
<properties refObjectId="4111" />
<object objectId="7111" />
<properties refObjectId="7111" />
</objects>
Then you should use the following xpath to get only objects 1111 and 7111. The result should not include 4111 because the properties where refObjectId = 4111 does not immediately follow the object whose objectId=4111.
//objects/properties[#refObjectId = preceding::object[1]/#objectId]/preceding::object[1]
Assuming that all <properties> nodes that belong to a given <object> actually follow that object (your input seems to imply that), you could do:
/objects/properties[
#refObjectId = preceding-sibling::object[1]/#objectId
and
not(#refPropertyId)
]/preceding-sibling::object[1]
This should perform pretty well.
If you happen to be in XSLT, things get a lot simpler:
<xsl:key name="kPropertiesByObjectId" match="properties" use="#refObjectId" />
and
<xsl:template match="object">
<!-- This tests for an empty node-set. Non-empty node sets can only happen
for objects with at least one <properties> node without #refPropertyId -->
<xsl:if test="key('kPropertiesByObjectId', #objectId)[not(#refPropertyId)]">
<xsl:copy-of select="." />
</xsl:if>
</xsl:template>
In the XSLT case, the order of object and proerties nodes becomes irrelevant.

Resources