Linq to xml - XDocument - How to read nested nodes - nested

I have below xml, my objective is that for given ProductName (for eample Spot) and given language for example ("en-gb") i want all translations. So in this case (ProductName=Spot and language="en-gb") the output should be TRADE STATUS, TRADE ID, VALUE DATE
I tried below linq query but it prints all the translations for "ProductType=Spot" instead of all translations for ProductType=Spot and language="en-gb"
var qry = doc.Descendants("Product")
.Where(p => p.Attribute("ProductName").Value == "Spot")
.Where(p =>
p.Element("Fields")
.Element("Field")
.Element("Translations")
.Element("Translation")
.Attribute("language")
.Value == "en-gb")
.Select(p => new { Text = p.Value });
It would be great if someone can suggest linq query for above objective.
<?xml version="1.0" encoding="utf-8" ?>
<Products>
<Product ProductName="Spot">
<Fields>
<Field FieldName="tradeStatus">
<Translations>
<Translation language="en-gb">TRADE STATUS</Translation>
<Translation language="fr-fr">fr_TRADE STATUS</Translation>
<Translation language="cz-cz">cz_TRADE STATUS</Translation>
</Translations>
</Field>
<Field FieldName="tradeId">
<Translations>
<Translation language="en-gb">TRADE ID</Translation>
<Translation language="fr-fr">fr_TRADEid</Translation>
<Translation language="cz-cz">cz_TRADEid</Translation>
</Translations>
</Field>
<Field FieldName="valueDate">
<Translations>
<Translation language="en-gb">VALUE DATE</Translation>
<Translation language="fr-fr">fr_ValueDate</Translation>
<Translation language="cz-cz">cz_ValueDt</Translation>
</Translations>
</Field>
</Fields>
</Product>
<Product ProductName="Forward">
<Fields>
<Field FieldName="dealtRate">
<Translations>
<Translation language="en-gb">DEALT RATE</Translation>
<Translation language="fr-fr">fr_dealtrt</Translation>
<Translation language="cz-cz">cz_dr</Translation>
</Translations>
</Field>
<Field FieldName="dealtAmount">
<Translations>
<Translation language="en-gb">DEALT AMOUNT</Translation>
<Translation language="fr-fr">fr_dAmtt</Translation>
<Translation language="cz-cz">cz_dealtAmtt</Translation>
</Translations>
</Field>
</Fields>
</Product>
</Products>

I found the answer to my own question, below linq query works
var qry = doc.Descendants("Product")
.Where(p=>p.Attribute("ProductName").Value=="Spot").Descendants("Fields").Descendants("Translations").Descendants("Translation")
.Where(t => t.Attribute("language").Value == "en-gb")
.Select(t => new { Text = t.Value });

Related

How to change string of Purchase Status(purchase_state) that is in Purchase Request? (ODOO)

So I want to change the string of "Purchase Order" inside Purchase Status(Inside Purchase Request) to something like "PO Created" when the purchase_state is in [purchase] but I don't know how I can do it. I want to create fresh module as well.
Here' s what I tried so far. I've created an XML and inherit the view.
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="purchase_request_form_inherit" model="ir.ui.view">
<field name="name">purchase.request.inherit</field>
<field name="model">purchase.request</field>
<field name="inherit_id" ref="purchase_request.view_purchase_request_form"/>
<field name="arch" type="xml">
<field name="purchase_state" position="attributes">
<attribute name="attrs" string="PO Created" attrs="{'readonly': [('po_line.state','=', 'purchase')]}"/>
</field>
</field>
</record>
</odoo>
I prefer use xpath:
<record id="purchase_request_form_inherit" model="ir.ui.view">
<field name="name">purchase.request.inherit</field>
<field name="model">purchase.request</field>
<field name="inherit_id" ref="purchase_request.view_purchase_request_form"/>
<field name="arch" type="xml">
<field expr="field[#name='purchase_state']" position="attributes">
<!-- To change the String -->
<attribute name="string">PO Created</attribute>
<!-- To change the attrs -->
<attribute name="attrs">{'readonly': [('po_line.state','=', 'purchase')]}</attribute>
</field>
</field>
</record>
I hope this answer could be helpful for you.

Odoo Inherit view can't set invisible attribute

I am odor newer.
I want to use the sale.order field and value to create a custom report by select some specific
field from sale.order.
I have created a custom model to inherit sale.order model.
And create a view to inherit view of sale.order.
Here is my code:
class SaleOrder(models.Model):
_inherit = 'sale.order'
<field name="name">Custom Sale Report</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,form</field>
<field name="name">sale.order.inherited</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_tree" />
<field name="mode">primary</field>
<field name="arch" type="xml">
<xpath expr="//field[#name='name']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath> </field> </record>
But I don't know why the invisible attribute is not working.
Please Help. Thanks.
Try this.
<field name="name">sale.order.inherited</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_tree" />
<field name="arch" type="xml">
<xpath expr="//field[#name='name']" position="replace">
<field name="name" optional="hide"/>
</xpath>
</field>
</record>

How do i customise product template views by inheritance in odoo 14?

I'm trying to add a custom field in product_templte_form_vieew by doing this :
<!-- product template -->
<record id="mymoduleproduct_view_form" model="ir.ui.view">
<field name="name">mymodule.product</field>
<field name="model">mymodule.product</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//notebook/page[#name='general_information']/group[2]" position="attributes">
<field name="prixass"/>
<field name="taxes_id" position="attributes">
<attribute name="invisible">1</attribute>
</field>
</xpath>
</field>
</record>
No error in excution but it seems to not work. Need help to detect or correct what is wrong.
I have already define ‘prixass’ fields like this :
class MyModuleProduct(models.Model):
_name = "mymodule.product"
_description = "table des articles"
_inherit = "product.template"
prixass = fields.Float(string='Prix Assurance')
taxes_id = fields.Many2many('account.tax', 'product_hospi_taxes', 'prod_hospi_id', 'tax_id', string='Customer Taxes')
supplier_taxes_id = fields.Many2many('account.tax', 'product_hospi_supplier_taxes', 'prod_hospi_id', 'tax_id', string='Vendor Taxes')
route_ids = fields.Many2many('stock.location.route', 'stock_route_product_hospi', 'product_hospi_id', 'route_id', string='Routes',)
Also i’ld like to remove the fields taxes_id from the view, how do i do ?
.
the resume of the question in image here
Thanks .
Try this.
class MyModuleProduct(models.Model):
_inherit = "product.template"
prixass = fields.Float(string='Prix Assurance')
taxes_id = fields.Many2many('account.tax', 'product_hospi_taxes', 'prod_hospi_id', 'tax_id', string='Customer Taxes')
supplier_taxes_id = fields.Many2many('account.tax', 'product_hospi_supplier_taxes', 'prod_hospi_id', 'tax_id', string='Vendor Taxes')
route_ids = fields.Many2many('stock.location.route', 'stock_route_product_hospi', 'product_hospi_id', 'route_id', string='Routes',)
<record id="product_inherit_view" model="ir.ui.view">
<field name="name">product.template</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//notebook/page[#name='general_information']/field[#name='default_code']" position="after">
<field name="prixass"/>
</xpath>
<field name="taxes_id" position="replace">
<field name="taxes_id" invisible="1"/>
</field>
</field>
</record>
but this work for me now
//model
class MyModuleProduct(models.Model):
_inherit = "product.template"
prixass = fields.Float(string='Prix Assurance')
taxes_id = fields.Many2many('account.tax', 'product_hospi_taxes', 'prod_hospi_id', 'tax_id', string='Customer Taxes')
supplier_taxes_id = fields.Many2many('account.tax', 'product_hospi_supplier_taxes', 'prod_hospi_id', 'tax_id', string='Vendor Taxes')
route_ids = fields.Many2many('stock.location.route', 'stock_route_product_hospi', 'product_hospi_id', 'route_id', string='Routes',)
//views
<record id="product_inherit_view" model="ir.ui.view">
<field name="name">product.template</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//notebook/page[#name='general_information']/group[1]" position="after">
<group>
<field name="prixass"/>
</group>
</xpath>
<field name="taxes_id" position="replace">
<field name="taxes_id" invisible="1"/>
</field>
</record>
thanks.

Getting values of fields in XML

I have the folling XML (as string)
xml = '''
<?xml version="1.0" encoding="utf-8"?>
<Response total="00:00:00.2130175">
<Result>
<Channel name="test">
<TotalCount ignoringpaging="2">2</TotalCount>
<Products>
<Product id="8050" ecommerceproduct="Productname">
<Fields>
<Field name="pid">8050</Field>
<Field name="ProductName">Productname</Field>
<Field name="ProductCategorie" culture="nl-NL">Category</Field>
<Field name="Titel" culture="nl-NL">Product Titel</Field>
<Field name="ProductHoogte">74</Field>
<Field name="ProductVerstelbaarheid">Vast</Field>
<Field name="ProductDikte">25</Field>
<Field name="ProductMateriaal">Gemelamineerd spaanplaat</Field>
<Field name="ProductLijn">0</Field>
<Field name="prodId">63258518</Field>
</Fields>
<Variants>
<Variant id="8060" ecommerceproduct="Productname">
<Fields>
<Field name="ProductName">Productname / Black</Field>
<Field name="PID">8060</Field>
<Field name="Zichtbaar">Y</Field>
<Field name="articleCode">123456</Field>
<Field name="priceExcl">469</Field>
<Field name="ProductBreedte">180</Field>
<Field name="ProductDiepte">80</Field>
<Field name="ProductHoogte">74</Field>
<Field name="varId">121655579</Field>
<Field name="visible">Y</Field>
</Fields>
</Variant>
</Variants>
</Product>
<Product id="8051" ecommerceproduct="Productname 2">
<Fields>
<Field name="pid">8051</Field>
<Field name="ProductName">Productname 2</Field>
<Field name="ProductCategorie" culture="nl-NL">Category</Field>
<Field name="Titel" culture="nl-NL">Product Titel 2</Field>
<Field name="ProductHoogte">74</Field>
<Field name="ProductVerstelbaarheid">Vast</Field>
<Field name="ProductDikte">25</Field>
<Field name="ProductMateriaal">Gemelamineerd spaanplaat</Field>
<Field name="ProductLijn">0</Field>
<Field name="prodId">63258520</Field>
</Fields>
<Variants>
<Variant id="8061" ecommerceproduct="Productname 2">
<Fields>
<Field name="ProductName">Productname 2 / White</Field>
<Field name="PID">8061</Field>
<Field name="Zichtbaar">Y</Field>
<Field name="articleCode">234567</Field>
<Field name="priceExcl">499</Field>
<Field name="ProductBreedte">180</Field>
<Field name="ProductDiepte">80</Field>
<Field name="ProductHoogte">74</Field>
<Field name="varId">216555798</Field>
<Field name="visible">N</Field>
</Fields>
</Variant>
</Variants>
</Product>
</Products>
</Channel>
</Result>
</Response>'''
with xml.etree I can iterate over the Products, but how can I get all the values of the fields and variants fields.
root = ET.fromstring(xml)
for p in root.iter('Product'):
print(p.attrib)
the output I get is:
{'id': '8050', 'ecommerceproduct': 'Productname'}
{'id': '8060', 'ecommerceproduct': 'Productname 2'}
So this seems to work, but whatever I try to get the values from the fields, I get no response.

Query all nodes with a special attribute value

I have a problem querying an XML structure.
This is the document:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<LangSet id="1031">
<field id="Language">1031</field>
<field id="PrimaryLanguage">7</field>
<Term id="18">
<field id="CreatedBy">dot_Termservice</field>
<field id="CreatedOn">20060905T170414Z</field>
<field id="CreatedOnUTC">20060905T150414Z</field>
<field id="CreatedOrUpdatedBy">dot_Termservice</field>
<field id="CreatedOrUpdatedOn">20080107T141350Z</field>
<field id="CreatedOrUpdatedOnUTC">20080107T121350Z</field>
<field id="Status">Negativterm.Kunden-orientiert;Negativterm.Technik-orientiert</field>
<field id="Term">Innenpersenning</field>
<field id="TermType">MainTerm</field>
<field id="UpdatedBy">dot_Termservice</field>
<field id="UpdatedOn">20080107T141350Z</field>
<field id="UpdatedOnUTC">20080107T121350Z</field>
<field id="UserId">11817</field>
</Term>
<Term id="19">
<field id="CreatedBy">dot_Termservice</field>
<field id="CreatedOn">20020626T120555Z</field>
<field id="CreatedOnUTC">20020626T100555Z</field>
<field id="CreatedOrUpdatedBy">dot_Termservice</field>
<field id="CreatedOrUpdatedOn">20020626T120555Z</field>
<field id="CreatedOrUpdatedOnUTC">20020626T100555Z</field>
<field id="Status">Vorzugsterm.Kunden-orientiert;Vorzugsterm.Technik-orientiert</field>
<field id="Term">Persenning</field>
<field id="TermType">MainTerm</field>
<field id="UserId">18088</field>
</Term>
<Term id="20">
<field id="CreatedBy">dot_Termservice</field>
<field id="CreatedOn">20011105T140407Z</field>
<field id="CreatedOnUTC">20011105T120407Z</field>
<field id="CreatedOrUpdatedBy">dot_Termservice</field>
<field id="CreatedOrUpdatedOn">20080107T141350Z</field>
<field id="CreatedOrUpdatedOnUTC">20080107T121350Z</field>
<field id="Status">Negativterm.Kunden-orientiert;Negativterm.Technik-orientiert</field>
<field id="Term">Verdeckabdeckung</field>
<field id="TermType">MainTerm</field>
<field id="UpdatedBy">dot_Termservice</field>
<field id="UpdatedOn">20080107T141350Z</field>
<field id="UpdatedOnUTC">20080107T121350Z</field>
<field id="UserId">32287</field>
</Term>
</LangSet>
<LangSet id="1031">
<field id="Language">1031</field>
<field id="PrimaryLanguage">7</field>
<Term id="8">
<field id="CreatedBy">dot_Termservice</field>
<field id="CreatedOn">20060905T170414Z</field>
<field id="CreatedOnUTC">20060905T150414Z</field>
<field id="CreatedOrUpdatedBy">dot_Termservice</field>
<field id="CreatedOrUpdatedOn">20070711T153241Z</field>
<field id="CreatedOrUpdatedOnUTC">20070711T133241Z</field>
<field id="Status">Vorzugsterm.Kunden-orientiert;Vorzugsterm.Technik-orientiert</field>
<field id="Term">Innenrad</field>
<field id="TermType">MainTerm</field>
<field id="UpdatedBy">dot_Termservice</field>
<field id="UpdatedOn">20070711T153241Z</field>
<field id="UpdatedOnUTC">20070711T133241Z</field>
<field id="UserId">11818</field>
</Term>
</LangSet>
</document>
All I want to do is to get all the Textvalues of the field elements with the attribute id=Term and return them in a LangSet as showned below:
<LangSet> <field id="Term">Innenpersenning</field> <field
id="Term">Persenning</field> <field id="Term">Verdeckabdeckung</field>
</LangSet>
<LangSet>
<field id="Term">Innenrad</field>
</LangSet>
<LangSet>
<field id="Term">Raumakustik</field>
</LangSet>
<LangSet>
<field id="Term">Fahrgastraumbeleuchtung</field> <field
id="Term">IB</field> <field id="Term">Innenbeleuchtung</field> <field
id="Term">Innenraumbeleuchtung</field>
</LangSet>
I'm getting the right values but unfortunatley not in a Langset node:
xquery version "1.0";
declare boundary-space strip;
declare namespace xs="http://www.w3.org/2001/XMLSchema";
for $x in doc("Sample.xml")/Document/Database/Dictionary/Concept/LangSet/Term//field
where $x/#id="Term"
return $x
I'm sure that it isn't that difficult but I'm stuck in documentation and I can't find the solution which works for me.
Thank you for any suggestions!
If you decide to return <LangSet> elements from your document, which contain appropriate <field> descendant elements, they will also contain all their other descendants.
If I understand what you want, you need to create on-the-fly some semi-clone elements reflecting partially your input document filtered and return them.
Scan LangSet-s and test each of them for desired descendants. If found, create appropriate output elements:
let $doc := doc("Sample.xml")
for $langset in $doc/document/LangSet
let $fields := $langset/descendant::field[#id = 'Term']
where exists($fields)
return
<LangSet>
{
for $field in $fields return
<field id='Term'>{string($field)}</field>
}
</LangSet>
You can solve this with an top-down approach like CiaPan's answer is or an bottom-up approach.
Based on the xml example you gave solutions could be:
Top-down
let $document := doc("langset.xml")/*
for $langset in $document/LangSet
let $fields := $langset//field[#id = 'Term']
return
<LangSet>
{ $fields }
</LangSet>
Bottom-up
let $document := doc("langset.xml")/*
for $field in $document//field[#id = 'Term']
group by $langset := $field/ancestor::LangSet
order by $langset descending
return
<LangSet>
{ $field }
</LangSet>

Resources