Use xmlstarlet to select nodes that do NOT contain a specific subnode - xmlstarlet

I have thousands of records similar to the one below
<holding>
<holding_id>2225031160001858</holding_id>
<record>
<leader>00210cx a22200085 454500</leader>
<controlfield tag="001">h38165-01alliance_ohsu</controlfield>
<controlfield tag="004">b10145746-01alliance_ohsu</controlfield>
<controlfield tag="005">20200417125900.0</controlfield>
<controlfield tag="008">2004170u\\\\0\\\0001aaund0999999</controlfield>
<datafield ind1="2" ind2=" " tag="852">
<subfield code="b">OHSUMAIN</subfield>
<subfield code="c">oldstorjrl</subfield>
</datafield>
</record>
</holding>
I need to change datafield #ind1 to " " where #tag="852" AND no subfield with #code="h" exists. In this example, #code="b" and #code="c" exist, but #code="h" does not, so I'd want to modify this record.
I can think of ways to accomplish what I need using program logic, but can I use xmlstarlet directly to select the nodes I want based on the absence of a subnode?
Desired output from this record would be
<holding>
<holding_id>2225031160001858</holding_id>
<record>
<leader>00210cx a22200085 454500</leader>
<controlfield tag="001">h38165-01alliance_ohsu</controlfield>
<controlfield tag="004">b10145746-01alliance_ohsu</controlfield>
<controlfield tag="005">20200417125900.0</controlfield>
<controlfield tag="008">2004170u\\\\0\\\0001aaund0999999</controlfield>
<datafield ind1=" " ind2=" " tag="852">
<subfield code="b">OHSUMAIN</subfield>
<subfield code="c">oldstorjrl</subfield>
</datafield>
</record>
</holding>

Not sure how I missed this, but it turned out to be straightforward
xmlstarlet ed -u '/holding/record/datafield[#tag="852"][not(subfield[#code="h"])]/#ind1' -v ' '

This xpath expression should select the correct target node:
"//datafield[#ind1][not(subfield[#code="h"])]"

Related

How to retrieve Itinerary remarks with GetReservationsRQ Api?

Running the command I¥ command returns:
2 AA1579X 16SEP 5 DFWORD HF1 0625 0846 /DCBA*SDAZXT /E
I have successfully sent a request using GetReservationRQ. Asking for the remarks sections but I am getting the result above which I would expect. (I assumed this is the right section and have tried Itinerary too, see below)
<GetReservationRQ version="1.1.0" xmlns="http://services.sabre.com/sp/updatereservation/v1_1">
<Profile>
<UniqueID id="......."/>
</Profile>
<SubjectAreas>
<SubjectArea>REMARKS</SubjectArea>
</SubjectAreas>
<ReturnOptions>
<ViewName>Default</ViewName>
<ResponseFormat>STL</ResponseFormat>
</ReturnOptions>
</GetReservationRQ>
Which returns 2 remarks as part of the response:
<Remarks>
<Remark id="44" index="1" type="HS">
<RemarkLines>
<RemarkLine>
<Text>POSSIBLE DUPE BOOKING. SEE PNR JZXWEI JBVFYC HUSTLM</Text>
</RemarkLine>
</RemarkLines>
</Remark>
<Remark id="45" index="2" type="HS">
<RemarkLines>
<RemarkLine>
<Text>POSSIBLE DUPE BOOKING. SEE PNR KDCFKD KQLLXF</Text>
</RemarkLine>
</RemarkLines>
</Remark>
</Remarks>
However as you can see they are not the same remark as when I run the command I¥. What am I doing wrong?
Here are links to the sabre documentation:
https://developer.sabre.com/docs/soap_apis/management/itinerary/Retrieve_Itinerary/help_doc?page=get-reservation-request-and-response-structure
Which says:
REMARKS Allows to display remark information (supported types: REG, HD, HS, CLIADR, DELADR, INVOICE, ITINERARY, INTERFACE, CODED_A, PRTONTKT, CORPORATE, FOP, QQ, FILLER, ITINSEGASSOC)

Select node using XPATH 1.0 and xmlstarlet containing specific text

From the XML below that begins as:
<?xml version="1.0" encoding="UTF-8"?><searchRetrieveResponse>
<version>1.2</version>
<numberOfRecords>1</numberOfRecords>
<records>
<record>
<recordSchema>marcxml</recordSchema>
<recordPacking>xml</recordPacking>
<recordData>
<record>
<leader>01448cam a2200445Ia 4500</leader>
<controlfield tag="001">9910650701858</controlfield>
<controlfield tag="005">20181227054218.2</controlfield>
<controlfield tag="008">930525s1941 nyu b 001 0 eng d</controlfield>
<datafield tag="035" ind1=" " ind2=" ">
<subfield code="a">(OCoLC)28157672</subfield>
</datafield>
<datafield tag="035" ind1=" " ind2=" ">
<subfield code="a">(OCoLC)ocm28157672</subfield>
</datafield>
<datafield tag="035" ind1=" " ind2=" ">
<subfield code="a">(EXLNZ-01ALLIANCE_NETWORK)99153881770001451</subfield>
</datafield>
<datafield tag="040" ind1=" " ind2=" ">
<subfield code="a">UTS</subfield>
<subfield code="b">eng</subfield>
<subfield code="c">UTS</subfield>
I need to select only the text node in /searchRetrieveResponse/records/record/recordData/record/datafield[#tag="035"]/subfield[#code="a"] that contains (EXLNZ-01ALLIANCE_NETWORK) using xmlstarlet (XPATH 1.0) so the desirable output is (EXLNZ-01ALLIANCE_NETWORK)99153881770001451
I have attempted many variations of xmlstarlet sel -T -t -m '/searchRetrieveResponse/records/record/recordData/record/datafield[#tag="035"]/subfield[#code="a"][text()[contains(.,'ALLIANCE_NETWORK')]]' -v '.' but I keep returning all the 035/subfield[#code="a"] rather than just the one I want. What am I doing wrong? Thanks
Figured it out -- contains filter wasn't set up properly. I'm posting only because I found matching the node awkward.
xmlstarlet sel -T -t -m '/searchRetrieveResponse/records/record/recordData/record/datafield[#tag="035"]/subfield[#code="a"][contains(text(), "ALLIANCE_NETWORK")]' -v '.'

sed multiline remove before pattern

Hi I have a big log file for which I am trying to get xml data passed into It.
I have a big log file which ressembles this :
2016/01/01 bladh bqskjdqskldjqsdlqskdjqlskdj dazihzmkldjkdjqslkjd
2016/01/01: qsdhqsdlkqsmdjqsldjqslkdjqlskdjqslkdjqslkdjqskdjqsd
2016/01/01: qsjdqmlskdmlqskdmcxxxx [qskjd][qsdjqslkdj] Payload :[<LOG><a>a</a>
<b>b</b>
<c>c</c>
<id>XXXXX</id>
<d>d</d>
</LOG>]]
2016/01/01 bladh bqskjdqskldjqsdlqskdjqlskdj dazihzmkldjkdjqslkjd
2016/01/01: qsdhqsdlkqsmdjqsldjqslkdjqlskdjqslkdjqslkdjqskdjqsd
2016/01/01: qsjdqmlskdmlqskdmcxxxx [qskjd][qsdjqslkdj] Payload :[<LOG> <a>a</a>
<b>b</b>
<c>c</c>
<id>YYYYY</id>
<d>d</d>
</LOG>]]
qskdmqlskdqlsdqlskdqlsdk
qsdlkqsdlkqsdmlkqsdlk
For now I am using
sed -n '/<START/{:start /\/END/!{N;b start};/XXXXX/p}' logFile
and I am getting this
2016/01/01: qsjdqmlskdmlqskdmcxxxx [qskjd][qsdjqslkdj] Payload :[<LOG><a>a</a>
<b>b</b>
<c>c</c>
<id>XXXXX</id>
<d>d</d>
</LOG>]]
I would like to retrieve the whole XML and get :
<LOG>
<a>a</a>
<b>b</b>
<c>c</c>
<id>XXXX</id>
<d>d</d>
</LOG>
Thanks in advance
Solution in TXR:
#(repeat)
# (skip)Payload :[<#tag>#preamble
# (collect)
#middle
# (last)
</#tag>]]
# (end)
# (output)
<#tag>
#(trim-str preamble)
# (repeat)
#middle
# (end)
</#tag>
# (end)
#(end)
Run:
$ txr extract.txr data
<LOG>
<a>a</a>
<b>b</b>
<c>c</c>
<id>XXXXX</id>
<d>d</d>
</LOG>
<LOG>
<a>a</a>
<b>b</b>
<c>c</c>
<id>YYYYY</id>
<d>d</d>
</LOG>
Try this:
sed -n '/<LOG/{:a;/<\/LOG/!{N;ba};s/.*\(<LOG>\)\(.*XXXXX.*<\/LOG>\).*/\1\n\2/p}' logFile
It should do the job but keep in mind that sed is not the right tool for parsing xml. When you'll have to parse valid xml files, you should consider using xmlstarlet or xmllint.
This might work for you (GNU sed):
sed -nr '/<LOG>/,/<\/LOG>/{s/.*(<LOG>)\s*/\1\n/;s/(<\/LOG>).*/\1/;p}' file
Use seds grep-like option to inhibit printing unless explicitly required and utilise the range feature /.../,/.../, top and tailing the string produced.

How to resolve this error - Uncaught Error: '2016-' is not a correct date, datetime nor time

I got the following part of code from Odoo community reference website for creating birthday calendar mark ups
.PY file
class birthday_report(osv.osv):
_name = "birthday.report"
_auto = False
_columns = {
'name': fields.many2one('hr.employee','Employee', readonly=True),
'dob' : fields.date('Birthday', readonly=True),
}
def init(self, cr):
tools.drop_view_if_exists(cr, 'birthday_report')
cr.execute("""
create or replace view birthday_report as (
select
h.id as id,
h.id as name,
concat(concat(date_part('Year',current_date),'-'),to_char(h.birthday, 'mm-dd')) as dob
from
hr_employee as h
join
resource_resource as r
on
h.resource_id=r.id
where r.active ='t'
)
""")
birthday_report()
.XML file
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_birthday_report_calendar" model="ir.ui.view">
<field name="name">Employee Birthday</field>
<field name="model">birthday.report</field>
<field name="arch" type="xml">
<calendar string="Birthday" color="name"
date_start="dob"
quick_add="False" avatar_model="hr.employee">
<field name="name"/>
</calendar>
</field>
</record>
<record model="ir.actions.act_window" id="action_birthday_view">
<field name="name">Birthday</field>
<field name="res_model">birthday.report</field>
<field name="view_type">form</field>
<field name="view_mode">calendar</field>
<field name="view_id" eval="view_birthday_report_calendar"/>
<field name="domain">[]</field>
</record>
<menuitem id="menu_birthday" name="Birthday" parent="hr.menu_hr_root" groups="base.group_user"/>
<menuitem id="menu_view_birthday" parent="menu_birthday" action="action_birthday_view" groups="base.group_user"/>
</data>
</openerp>
Error shows up when I navigate to January or previous year December, the following error occurs :
Uncaught Error: '2016-' is not a correct date, datetime nor time.
I am new to sql queries in Odoo, Anyone with suggestions on this would be really grateful. Thanks !!
First, I recommend using || instead of concat. That allows you to do multiple concatenations.
date_part('Year',current_date) || '-' || to_char(h.birthday, 'mm-dd')
Secondly I recommend casting to date, so
(date_part('Year',current_date) || '-' || to_char(h.birthday, 'mm-dd'))::date
Third, what happens if you just use psql and select from the view? Are there malformed dates? Or is something else happening elsewhere in your Python code?

XML Parsing error in Flex

I am passing a XML document form the Java to Flex using Remote Object.
My XML is as follows
"
<root
<dept ID="1" Name="RND"
<Emp ID="1" Name="Aj"/>
</dept>
<dept ID="2" Name="ENG">
<Emp ID="1" Name="Aj"/>
</dept>
<dept ID="3" Name="MECH">
<Emp ID="1" Name="Aj"/>
</dept>
</root>
"
In Flex i am trying to access using below code
treeData = event.result as XML;
deptTree.dataProvider = treeData;
When i am trying to access the result object and i am getting the below exception
"
[RPC Fault faultString="org.w3c.dom.DOMException : INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified. " faultCode="Server.Processing" faultDetail="null"]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultHandler()
at mx.rpc::Responder/fault()
at mx.rpc::AsyncRequest/fault()
at NetConnectionMessageResponder/statusHandler()
at mx.messaging::MessageResponder/status()
"
Please help me to resolve this issue.
Thanks in advance.
Aj
<root
<dept ID="1" Name="RND"
Close root tag:
<root>

Resources