Ruby Hash declaration with an inline block in the middle - ruby-on-rails

Here is an XML document:
<Request>
<Field1>value1</Field1>
<Field2>value2</Field2>
<Section1>
<Field attribute1="attrval1">value11</Field>
<Field attribute1="attrval2">value12</Field>
<Field attribute1="attrval3">value13</Field>
<Field attribute1="attrval4">value14</Field>
</Section1>
<Section2>
<Fld1>value21</Fld1>
<Fld2>value22</Fld2>
<Fld3>value23</Fld3>
</Section2>
</Request>
which is parsed by following Ruby code:
xml = Nokogiri::XML(request.raw_post)
req = xml.xpath('/Request')
hash = {
field1: req.xpath('Field1').text,
field2: req.xpath('Field2').text,
section1: req.xpath('Section1/Field').map {|fld|
{
attribute1: fld.attr('attribute1'),
value: fld.text
}
},
section2: req.xpath('Section2').some_method { |sec2|
{
fld1: sec2.xpath('Fld1').text,
fld2: sec2.xpath('Fld2').text,
fld3: sec2.xpath('Fld3').text
}
}
}
Parsing of Section1 is a real working piece of code.
Parsing of non-repeated values in Section2 is a concept - something I would like to see to not have to declare
sec2 = req.xpath('Section2')
before hash declaration.
I would like to see some inline block.
Any suggestions?

Not answer, but as alternative you could try:
ActiveSupport::XmlMini.parse(xml)
{"Request"=>
{"Field1"=>{"__content__"=>"value1"},
"Field2"=>{"__content__"=>"value2"},
"Section1"=>
{"Field"=>
[{"attribute1"=>"attrval1", "__content__"=>"value11"},
{"attribute1"=>"attrval2", "__content__"=>"value12"},
{"attribute1"=>"attrval3", "__content__"=>"value13"},
{"attribute1"=>"attrval4", "__content__"=>"value14"}]},
"Section2"=>
{"Fld1"=>{"__content__"=>"value21"},
"Fld2"=>{"__content__"=>"value22"},
"Fld3"=>{"__content__"=>"value23"}}}}

You could use map here, too:
req.xpath('Section2/*').map { |f| [f.name.downcase.to_sym, f.text] }.to_h
# => {:fld1=>"value21", :fld2=>"value22", :fld3=>"value23"}

Related

how to parse a xml in erlang?

I have this string with xml extract in a tuple list:
MessageResponse = [{"code",0},{"description","description"},{"respuestaServicioSoap",{{"executeWebServiceSolutionResult",{{"CEDULARUCSpecified", false},{"AUTORIZACION", "00000012431781"},{"AUTORIZACIONSpecified",true},{"RESULTADO","000"},{"CODIGO_RESULTADOSpecified",true},{"COD_PAGO","00000012431781"},{"COD_PAGOSpecified",true},{"COMISION",{{"string","0"}}},{"COMISIONSpecified", true},{"DIRECCIONSpecified", false},{"FECHA_COMPENSACIONSpecified", false},{"FECHA_TRANSACCION","20170116"},{"FECHA_TRANSACCIONSpecified",true},{"FECHORA_SW","20170116123951"},{"FECHORA_SWSpecified",true},{"HORA_TRANSACCION","123951"},{"HORA_TRANSACCIONSpecified",true},{"MENSAJE","TRANSACCION OK"},{"MENSAJESpecified",true},{"NOMBRESpecified",false},{"PRODUCTO","0010761005"},{"PRODUCTOSpecified",true},{"SECUENCIA_ADQ","2833"},{"SECUENCIA_ADQSpecified",true},{"SECUENCIA_SW","576167"},{"SECUENCIA_SWSpecified",true},{"TERMINAL","0696069603000001"},{"TERMINALSpecified",true},{"TYPE_TRNSpecified",false},{"VALOR_TOTAL", { { "string", "0" }}},{"VALOR_TOTALSpecified",true},{"XML_ADDSpecified",false},{"XML_DATASpecified",false},{"XML_FACT","<XML_FACT>\r\n <DATOS_FACT>\r\n <LINEA_1>REPRESENTACIONES ORMAN S.A.</LINEA_1>\r\n <LINEA_2>RUC: 0987654321</LINEA_2>\r\n <LINEA_3 />\r\n <LINEA_4 />\r\n <LINEA_5>FACTURA: 001-627-0000048745</LINEA_5>\r\n <LINEA_6>CLAVE: </LINEA_6>\r\n <LINEA_7>COMISION POR SERVICIO</LINEA_7>\r\n <LINEA_8>RECAUDACION EEAAPP - CUENTA: 11223344</LINEA_8>\r\n <LINEA_12>FACTURA: 001-627-0000048745 - CONSULTE SU DOCUMENTO EN WWW.LITO.COM/DOCUMENTOSELECTRONICOS</LINEA_12>\r\n <MSGCOMP />\r\n <MSGFACT />\r\n </DATOS_FACT>\r\n</XML_FACT>"},{"XML_FACTSpecified",true},{"XML_REPLY_CONSULTASpecified",false},{"XML_REPLY_PAGOSSpecified",false}}},{"executeWebServiceSolutionResultSpecified", true}}},{"result", "ok"}]
and need to get the text in LINEA_5 tag, any idea how to do it?
with this code:
{Xml, _Rest} = xmerl_scan:string(XmlFactura).
[#xmlText{value=Linea5}] = xmerl_xpath:string("//LINEA_5/text()", Xml).
the OTP library xmerl provides all the functions to manipulate XML files or string. It provides a set of record that help to handle different elements.
documentation is available here
The records are defined in erlXX/lib/xmerl-YYY/include/xmerl.hrl:
#xmlText{}
#xmlElement{}
#xmlPI{}
#xmlComment{}
#xmlDecl{}
[edit]
The xml data that you provide in your example is already modified, so I take an example from my own. Consider an xml file with the content:
<?xml version="1.0" encoding="UTF-8"?> <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="uuid_id">
<metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:calibre="http://calibre.kovidgoyal.net/2009/metadata" xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:creator opf:role="aut" opf:file-as="Ahern, Cecelia">Cecelia Ahern</dc:creator>
<dc:publisher>J'ai Lu</dc:publisher>
<meta name="calibre:title_sort" content="Si tu me voyais maintenant"/>
<dc:description>description blah blah</dc:description>
<meta name="calibre:timestamp" content="2012-03-18T18:04:20+00:00"/>
<dc:title>Si tu me voyais maintenant</dc:title>
<meta name="cover" content="cover"/>
<dc:date>2012-03-18T18:04:23+00:00</dc:date>
<dc:contributor opf:role="bkp">calibre (0.8.42) [http://calibre-ebook.com]</dc:contributor>
<dc:identifier opf:scheme="ISBN">9782290006504</dc:identifier>
<dc:identifier id="uuid_id" opf:scheme="uuid">7d062b17-258e-4268-9d46-a753c063c969</dc:identifier>
<dc:subject>Chick-lit</dc:subject>
<meta name="calibre:user_categories" content="{}"/>
<meta name="calibre:author_link_map" content="{"Cecelia Ahern": ""}"/>
<dc:language>fr</dc:language>
</metadata>
<manifest>
<item href="cover.jpeg" id="cover" media-type="image/jpeg"/>
</manifest>
<spine toc="ncx">
<itemref idref="titlepage"/>
</spine>
<guide>
<reference href="titlepage.xhtml" type="cover" title="Cover"/>
</guide> </package>
It is extract from an epub book, and stored in a file "content.opf". If I want to get the author name (line 4) I can do:
1> rr("C:\\My programs\\erl8.2\\lib\\xmerl-1.3.12\\include\\xmerl.hrl").
2> {Xml,_} = xmerl_scan:file("../doc/content.opf"),
2> Content = Xml#xmlElement.content,
2> [MetaRec] = [X || X <- Content, X#xmlElement.name == metadata],
2> Meta = MetaRec#xmlElement.content,
2> [CreatRec] = [X || X <- Meta, X#xmlElement.name == 'dc:creator'],
2> Creat = CreatRec#xmlElement.content,
2> [CreatText] = [X || X <- Creat, is_record(X,xmlText)],
2> Aut = CreatText#xmlText.value.
"Cecelia Ahern"

protobuf text format parsing maps

This answer clearly shows some examples of proto text parsing, but does not have an example for maps.
If a proto has:
map<int32, string> aToB
I would guess something like:
aToB {
123: "foo"
}
but it does not work. Does anyone know the exact syntax?
I initially tried extrapolating from an earlier answer, which led me astray, because I incorrectly thought multiple k/v pairs would look like this:
aToB { # (this example has a bug)
key: 123
value: "foo"
key: 876 # WRONG!
value: "bar" # NOPE!
}
That led to the following error:
libprotobuf ERROR: Non-repeated field "key" is specified multiple times.
Proper syntax for multiple key-value pairs:
(Note: I am using the "proto3" version of the protocol buffers language)
aToB {
key: 123
value: "foo"
}
aToB {
key: 876
value: "bar"
}
The pattern of repeating the name of the map variable makes more sense after re-reading this relevant portion of the proto3 Map documentation, which explains that maps are equivalent to defining your own "pair" message type and then marking it as "repeated".
A more complete example:
proto definition:
syntax = "proto3";
package myproject.testing;
message UserRecord {
string handle = 10;
bool paid_membership = 20;
}
message UserCollection {
string description = 20;
// HERE IS THE PROTOBUF MAP-TYPE FIELD:
map<string, UserRecord> users = 10;
}
message TestData {
UserCollection user_collection = 10;
}
text format ("pbtxt") in a config file:
user_collection {
description = "my default users"
users {
key: "user_1234"
value {
handle: "winniepoo"
paid_membership: true
}
}
users {
key: "user_9b27"
value {
handle: "smokeybear"
}
}
}
C++ that would generate the message content programmatically
myproject::testing::UserRecord user_1;
user_1.set_handle("winniepoo");
user_1.set_paid_membership(true);
myproject::testing::UserRecord user_2;
user_2.set_handle("smokeybear");
user_2.set_paid_membership(false);
using pair_type =
google::protobuf::MapPair<std::string, myproject::testing::UserRecord>;
myproject::testing::TestData data;
data.mutable_user_collection()->mutable_users()->insert(
pair_type(std::string("user_1234"), user_1));
data.mutable_user_collection()->mutable_users()->insert(
pair_type(std::string("user_9b27"), user_2));
The text format is:
aToB {
key: 123
value: "foo"
}

VBA force SAX to encode UTF-8 and indent

I'm writing VBA to export xml.
I use SAXXMLReader because I need pretty indented output.
This is what I want the declaration to look like:
<?xml version="1.0" encoding="UTF-8"?>
This is what it turns out as:
<?xml version="1.0" encoding="UTF-16" standalone="no"?>
Why is SAX ignoring my encoding selection and how do I force it to use 8.
Sub XML_Format_Indent_Save(xmlDoc1 As MSXML2.DOMDocument60, strOutputFile As String)
Dim xmlWriter As MSXML2.MXXMLWriter60
Dim strWhole As String
Set xmlWriter = CreateObject("MSXML2.MXXMLWriter")
xmlWriter.omitXMLDeclaration = False
xmlWriter.Indent = True
xmlWriter.Encoding = "utf-8"
With CreateObject("MSXML2.SAXXMLReader")
Set .contentHandler = xmlWriter
.putProperty "http://xml.org/sax/properties/lexical-handler", xmlWriter
.Parse xmlDoc1
End With
strWhole = xmlWriter.output
ExportStringToTextFile strOutputFile, strWhole
End Sub
From what I read in another post, you need to set .byteOrderMark to either true or false, otherwise the .encoding is ignored.

hyperlink in openerp tree view

I want to add a link with ftp url in my tree view. i tested with adding widget="url" in my xml ,but its not working.
Please help
my code is
<tree string="File Names" >
<field name="time_created" string="Time Created"/>
<field name="size" string="Size"/>
<field name="file_name"/>
<field name="file_path" widget="url"/>
</tree>
class filedata(osv.osv):
_name = 'filedata'
_log_access = False
_columns = {
'file_name' : fields.char('Name'),
'file_path' : fields.char('File Path'),
'time_created' : fields.datetime('Date Time'),
'size' : fields.char('Size')
}
download this module and you can get clear idea of putting link in tree view. Hope this will help you.
https://www.openerp.com/apps/6.1/web_url/

Parse Xml tags with attributes

I have this xml :
<document-display>
<name>
<entry lang="nl">nl Text</entry>
<entry lang="fr">fr Text</entry>
<entry lang="en">en Text</entry>
</name>
</document-display>
I would like to get the text according to the langage.
I'm using XmlSlurper.
With my current code :
def parsedD = new XmlSlurper().parse(xml)
parsedD."document-display".name.entry.each {it.#lang == 'fr'}
I have as bad result which is the concatenation of the 3 text content :
nl Textfr Texten Text
Thanks for helping.
Try
parsedD.name.entry.find { it.#lang == 'fr' }?.text()

Resources