Accessing Nokogiri element children - ruby

Upon parsing an html table, I am able to get the first row of the table as a Nokogiri element.
2.2.1 :041 > pp content[1]; nil
#(Element:0x3feee917d1e0 {
name = "tr",
children = [
#(Element:0x3feee917cfd8 {
name = "td",
attributes = [
#(Attr:0x3feee917cf74 { name = "valign", value = "top" })],
children = [
#(Element:0x3feee917ca60 {
name = "a",
attributes = [
#(Attr:0x3feee917c9fc {
name = "href",
value = "/cgi-bin/own-disp?action=getowner&CIK=0001513362"
})],
children = [ #(Text "Maestri Luca")]
})]
}),
#(Text "\n"),
#(Element:0x3feee917c150 {
name = "td",
children = [
#(Element:0x3feee917d794 {
name = "a",
attributes = [
#(Attr:0x3feee9179fb8 {
name = "href",
value = "/cgi-bin/browse-edgar?action=getcompany&CIK=0001513362"
})],
children = [ #(Text "0001513362")]
})]
}),
#(Text "\n"),
#(Element:0x3feee91796a8 {
name = "td",
children = [ #(Text "2016-09-04")]
}),
#(Text "\n"),
#(Element:0x3feee9179194 {
name = "td",
children = [ #(Text "officer: Senior Vice President, CFO")]
}),
#(Text "\n")]
})
=> nil
This is the content from the row:
Maestri Luca 0001513362 2016-09-04 officer: Senior Vice President, CFO
I need to access the Name, Number, Date and Title from the Nokogiri element.
One way of doing it is as below:
2.2.1 :042 > pp content[1].text; nil
"Maestri Luca\n0001513362\n2016-09-04\nofficer: Senior Vice President, CFO\n"
However, I am looking for a way of accessing the elements individually, not as one long sting with newline characters. How can I do it?

name, number, date, title = *content[1].css('td').map(&:text)
if content[1] is a tr, content[1].css('td') will find all td elements beneath it, .map(&:text) will call td.text for each of those td and put it into an array, which we than splat with * so we can do multiple assignment.
(Note: next time, please include the original HTML fragment, not the Nokogiri node inspect result.)

Related

Return multiple results with index terraform

I currently have the below lists,
local.security_list =
[
{
ocid = security_list_id_1
name = subnet1
},
{
ocid = security_list_id_2
name = subnet1
},
{
ocid = security_list_id_3
name = subnet2
},
{
name = subnet2
ocid = security_list_id_4
},
]
var.vcn_security_lists = [
{
security_list_name = security_list_1
subnet_name = subnet1
},
{
security_list_name = security_list_2
subnet_name = subnet1
},
{
security_list_name = security_list_3
subnet_name = subnet2
}
]
I want to create the security lists using the var.vcn_security_lists list and then assign them to the subnet later on by using the subnet_name field. I have done this previously using the index() function as below, which loops through a subnet and pulls out the security list with the same subnet name. The problem is that this only returns one item - how can I return multiple from a list ?
subnet_security_list_ocid = [local.security_list[index(local.security_list.*.name,var.vcn_security_lists[index(var.vcn_security_lists.*.subnet_name,var.vcn_subnets[count.index].subnet_name)].security_list_name)].id]

How to Convert a string to lua code to read value from nested table

I have a configurable value of a table fetch function which i get as an input string. I need that string to be executed as a code and fetch a value from the nested table.
I tried using load(string), its not working
local function main()
local t = {
["name1"] = "value1",
["name2"] = {["name1"] = "value1",
["name2"] = { 1, false, true, 23.54, "a \021 string" },
name3 = nil
},
name3 = nil
}
local string = 't.name2.name1'
print(type(string))
print(load(string))
end
print(load(string)) should print value1.
Below code works
local function main()
t = {
["name1"] = "value1",
["name2"] = {["name1"] = "value1",
["name2"] = { 1, false, true, 23.54, "a \021 string" },
name3 = nil
},
name3 = nil
}
string = "t.name2.name1"
print(type(string))
val = load("return "..string)()
print(val)
end

Correct way to filter an array in graphql

I have the following arrangement:
const Person = function(name, age, interest) {
this.name = name;
this.age = age;
this.interest = interest;
}
const people = [
new Person("rajat", 29, ['prog','food','gym']),
new Person("ravi", 23, ['travel', 'cook', 'eat']),
new Person("preeti", 19, ['comedy', 'arts', 'beauty'])
];
const schema = buildSchema(`
type Person {
name: String,
age: Int,
interest: [String]
},
type Query {
hello: String,
giveTen(input: Int!): Int,
person(name: String!): Person!,
}
`);
const root = {
hello: () => 'Hello World',
giveTen: (args) => args.input * 10,
person: (args) => people.filter(item => item.name === args.name),
};
When I run the following query:
query PersonDetails {
person(name: "rajat") {
name
age
interest
}
}
I get bunch of nulls, when there clearly is matching data in people array.
{
"data": {
"person": {
"name": null,
"age": null,
"interest": null
}
}
}
What you return inside your resolver needs to match the type for that particular field. Inside your schema, you've specified the Root Query field person should return a Person type, not a List (array) of that type.
Array.prototype.filter() always returns an array.
If you want to return a single object from people, you should use Array.prototype.find() instead, which will return the first element that matches the test (or null if none are found).
If you want to return all possible matches, you'll need to change your schema to reflect that (change the return type from Person to [Person]). Then you can keep using filter and it should work as expected.

How to put an XML document into another with Nokogiri

I want to include an xml document with arbitrary user provided data in another one using nokogiri.
I have tried Node#add_child and encountered a problem: nokogiri looses namespace definition if there is a uri in child_doc that is also present in main doc but with a different prefix.
Example:
doc = Nokogiri::XML %(
<s:rack xmlns:s="urn://shelf">
<s:shelf></s:shelf>
</s:rack>
)
child_doc = Nokogiri::XML %(
<m:shelf xmlns:m="urn://shelf">
<m:book></m:book>
</m:shelf>
)
doc.root.add_child(child_doc.root)
doc.to_xml
# =>
# <s:rack xmlns:s="urn://shelf">
# <s:shelf/>
# <!-- namespace for prefix m is not declared! -->
# <m:shelf>
# <m:book/>
# </m:shelf>
# </s:rack>
Namespace for prefix m is lost.
Here is the resulting doc object, pretty printed:
#(Document:0x1b2ce28 {
name = "document",
children = [
#(Element:0x1b327c4 {
name = "rack",
namespace = #(Namespace:0x1b320a8 { prefix = "s", href = "urn://shelf" }),
children = [
#(Text "\n "),
#(Element:0x1b45f90 { name = "shelf", namespace = #(Namespace:0x1b320a8 { prefix = "s", href = "urn://shelf" }) }),
#(Text "\n "),
#(Element:0x1a9e5d8 {
name = "shelf",
namespace = #(Namespace:0x1a87450 { prefix = "m", href = "urn://shelf" }),
children = [
#(Text "\n "),
#(Element:0x1a41dec { name = "book", namespace = #(Namespace:0x1a87450 { prefix = "m", href = "urn://shelf" }) }),
#(Text "\n ")]
})]
})]
})
As you can see internally namespaces in added nodes are correct but they are serialized wrong. How do I get nokogiri to save them in the resulting xml?

How do I format this json correctly?

Having a problem translating my json code form this dataObject...
var dataObject = {
"timeline":
{
"headline":"The Main Timeline Headline Goes here",
"type":"default",
"text":"<p>Intro body text goes here, some HTML is ok</p>",
"asset": {
"media":"http://yourdomain_or_socialmedialink_goes_here.jpg",
"credit":"Credit Name Goes Here",
"caption":"Caption text goes here"
},
"date": [
{
"startDate":"2011,12,10",
"endDate":"2011,12,11",
"headline":"Headline Goes Here",
"text":"<p>Body text goes here, some HTML is OK</p>",
"asset": {
"media":"http://twitter.com/ArjunaSoriano/status/164181156147900416",
"thumbnail":"optional-32x32px.jpg",
"credit":"Credit Name Goes Here",
"caption":"Caption text goes here"
}
}
],
"era": [
{
"startDate":"2011,12,10",
"endDate":"2011,12,11",
"headline":"Headline Goes Here",
"text":"<p>Body text goes here, some HTML is OK</p>",
}
]
}
}
into this method...
def timeline
t = {}
t['timeline'] = {}
t['timeline']['headline'] = "Lorem"
t['timeline']['text'] = "default"
t['timeline']['asset'] = {}
t['timeline']['asset']['media'] = ""
t['timeline']['asset']['credit'] = ""
t['timeline']['asset']['caption'] = ""
t['timeline']['date'] = [{}]
t['timeline']['date']['startDate'] = "2011,12,10"
t['timeline']['date']['endDate'] = "2011,12,11"
t['timeline']['date']['headline'] = ""
t['timeline']['date']['text'] = ""
t['timeline']['date']['asset'] = {}
t['timeline']['date']['asset']['media'] = ""
t['timeline']['date']['asset']['thumbnail'] = ""
t['timeline']['date']['asset']['credit'] = ""
t['timeline']['date']['asset']['caption'] = ""
t['timeline']['era'] = [{}]
t['timeline']['era']['startDate'] = "2011,12,10"
t['timeline']['era']['endDate'] = "2011,12,11"
t['timeline']['era']['headline'] = ""
t['timeline']['era']['text'] = ""
return t
end
specifically I'm uncertain about
t['timeline']['date'] = [{}]
and
t['timeline']['era'] = [{}]
How should I properly write those lines?
t['timeline']['date'] = [{}]
that should work just fine. Only you have to add attributes slightly different. Like this:
t['timeline']['date'][0]['startDate'] = "2011,12,10"
^^^
first element in the array
Just build a hash directly:
def timeline
{
"timeline" = {
"headline" = "Lorem",
"text" = "default",
"asset" = {}
},
"date" = [{
"startDate" = "2011,12,10",
"asset" = {
"media" = ""
}
}]
}
end
Saves a lot of typing, and will mentally map much more naturally to JSON.

Resources