Getting certain attributes based on other attributes in Nokogiri? - ruby

Here's the XML I'm working with:
<order xmlns="http://example.com/schemas/1.0">
<link type="application/xml" rel="http://example.com/rel/self" href="https://example.com/orders/1631"/>
<link type="application/xml" rel="http://example.com/rel/order/history" href="http://example.com/orders/1631/history"/>
<link type="application/xml" rel="http://example.com/rel/order/transition/release" href="https://example.com/orders/1631/release"/>
<link type="application/xml" rel="http://example.com/rel/order/transition/cancel" href="https://example.com/orders/1631/cancel"/>
<state>hold</state>
<order-number>123-456-789</order-number>
<survey-title>Testing</survey-title>
<survey-url>http://example.com/s/123456</survey-url>
<number-of-questions>6</number-of-questions>
<number-of-completes>100</number-of-completes>
<target-group>
<country>
<id>US</id>
<name>United States</name>
</country>
<min-age>15</min-age>
</target-group>
<quote>319.00</quote>
<currency>USD</currency>
</order>
What I need to do is get the href attribute, from the link that has a rel of http://example.com/rel/order/transition/release
So, how can I do that using Nokogiri?

Easy-peasy:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<order xmlns="http://example.com/schemas/1.0">
<link type="application/xml" rel="http://example.com/rel/self" href="https://example.com/orders/1631"/>
<link type="application/xml" rel="http://example.com/rel/order/history" href="http://example.com/orders/1631/history"/>
<link type="application/xml" rel="http://example.com/rel/order/transition/release" href="https://example.com/orders/1631/release"/>
<link type="application/xml" rel="http://example.com/rel/order/transition/cancel" href="https://example.com/orders/1631/cancel"/>
<state>hold</state>
<order-number>123-456-789</order-number>
<survey-title>Testing</survey-title>
<survey-url>http://example.com/s/123456</survey-url>
<number-of-questions>6</number-of-questions>
<number-of-completes>100</number-of-completes>
<target-group>
<country>
<id>US</id>
<name>United States</name>
</country>
<min-age>15</min-age>
</target-group>
<quote>319.00</quote>
<currency>USD</currency>
</order>
EOT
href = doc.at('link[rel="http://example.com/rel/order/transition/release"]')['href']
=> "https://example.com/orders/1631/release"
This is using Nokogiri's ability to use CSS accessors. Sometimes it's easier (or the only way) to use XPath, but I prefer CSS because they tend to be more readable.
Nokogiri::Node.at can take a CSS accessor or XPath, and will return the first node matching that pattern. If you need to iterate over all the matches, use search instead, which returns a NodeSet, which you can treat as an array. Nokogiri also supports at_xpath and at_css along with css and xpath for at and search symmetry.

That's a one-liner:
#doc.xpath('//xmlns:link[#rel = "http://example.com/rel/order/transition/release"]').attr('href')

Related

Laravel 5.1 linking style sheet not working

I am probably missing something very simple but, when I link my style sheet I get:
<link media="all" type="text/css" rel="stylesheet" href="http://laravel.dev:8000/public/css/masterCss.css">
showing on the webpage rather then linking to my css file.
My Html looks like:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>The Nub Life</title>
{{ Html::style('/public/css/masterCss.css') }}
</head>
<body>
#yield('content')
</body>
</html>
Why is this happening and how can I fix it?
the stylesheet href url, should not contain the word public. this is how you can generate url for your css asset files
<link media="all" type="text/css" rel="stylesheet" href="{{ URL::asset('css/masterCss.css') }}">
Suppose you have a .css file in your public/your_project_name/css/style.css
Simply write
<link href="{{ URL::asset('your_project_name/css/style.css') }}" rel="stylesheet">

Illegal character in query: not a URL code point

I have a validator problem:
Bad value http://fonts.googleapis.com/css?family=Dosis:400,700,800|Varela+Round|Architects+Daughter for attribute href on element link: Illegal character in query: not a URL code point.
But I have the follow code, no spaces anywhere:
<link href="http://fonts.googleapis.com/css?family=Dosis:400,700,800|Varela+Round|Architects+Daughter/" rel="stylesheet" type="text/css">
in the link href change | by %7C
There are 2 ways to fix this validation problem:
URL encode the | (vertical bar/line) character in the href attribute of the link element (as %7C) :
<link href="http://fonts.googleapis.com/css?family=Dosis:400,700,800%7CVarela+Round%7CArchitects+Daughter" rel="stylesheet" type="text/css">
Separate fonts inclusion with multiple link elements :
<link href="http://fonts.googleapis.com/css?family=Dosis:400,700,800" rel="stylesheet" type="text/css">
<link href="http://fonts.googleapis.com/css?family=Varela+Round" rel="stylesheet" type="text/css">
<link href="http://fonts.googleapis.com/css?family=Architects+Daughter" rel="stylesheet" type="text/css">
Avoid illegal characters such as empty space. For example, instead of <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Carter One" /> use <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Carter+One" />.

Tweak IE Conditional Comment with Nokogiri without converting entities

I have an XHTML file with an HTML5 Shiv in the head:
<!--[if lt IE 9]>
<script src='../common/html5.js' type='text/javascript'></script>
<![endif]-->
Using Nokogiri I need to adjust the path in that comment, stripping off the ../. However, any changes to the .content of the comment node results in XML output that converts the > and < to entities:
XML = <<ENDXML
<r><!--[if lt IE 9]>
<script src='../common/html5.js' type='text/javascript'></script>
<![endif]--></r>
ENDXML
require 'nokogiri'
doc = Nokogiri.XML(XML)
comment = doc.at_xpath('//comment()')
comment.content = comment.content.sub('../','')
puts comment.to_xml
#=> <!--[if lt IE 9]>
#=> <script src='common/html5.js' type='text/javascript'></script>
#=> <![endif]-->
The original source is valid XML/XHTML. How can I get Nokogiri not to convert the entities inside this comment during tweaking?
The Nokogiri docs for content= say:
The string gets XML escaped, not interpreted as markup.
So rather than using that, you could replace the node with a new one, using replace and an explicitly created comment node:
XML = <<ENDXML
<r><!--[if lt IE 9]>
<script src='../common/html5.js' type='text/javascript'></script>
<![endif]--></r>
ENDXML
require 'nokogiri'
doc = Nokogiri.XML(XML)
comment = doc.at_xpath('//comment()')
# this line is the new one, replacing comment.content= ...
comment.replace Nokogiri::XML::Comment.new(doc, comment.content.sub('../',''))
# note `comment` is the old comment, so to see the changes
# look at the whole document
puts doc.to_xml
Output is:
<?xml version="1.0"?>
<r>
<!--[if lt IE 9]>
<script src='common/html5.js' type='text/javascript'></script>
<![endif]-->
</r>

how do I include multiple js files with lightbox v2?

When I include the js for lightbox it prevents my other js from running; which means my jquery nav and slide down effects for divs stop working. Am I including the files in the correctly? I tried the endconflict() in the top of my script but that didn't work. Any help is greatly appreciated.
Thx
<link rel="stylesheet" type="text/css" href="jquery-lightbox-0.5/css/jquery.lightbox-0.5.css" media="screen" /> <link rel="stylesheet" href="css/bootstrap.css" type="text/css">
<link rel="stylesheet" href="css/bootstrap-responsive.css" type="text/css">
<link rel="stylesheet" href="css/style.css" type="text/css">
***<link rel="stylesheet" href="css/lightbox.css" type="text/css" media="screen" />***
<script type="text/javascript" src="js/jquery.js"></script>
<script src="javascript/jquery-1.7.1.min.js"></script>
<script src="javascript/bootstrap.js"></script>
***<script type="text/javascript" src="../lightbox2.05/js/prototype.js"></script>
<script type="text/javascript" src="../lightbox2.05/js/scriptaculous.js"></script>
<script type="text/javascript" src="../lightbox2.05/js/lightbox.js"></script>***
<script>
<a href="images/Screen Shot 2012-02-27 at 9.51.49 PM.png" rel="lightbox">
<img src="../../images/Screen Shot 2012-02-27 at 9.56.49 PM.png" height="180" width="460" alt="">
</a>
The problem is that lighbox uses pieces of Scriptaculous and Prototype, which are other javascript libraries like jQuery is. They don't play nicely with each, so you have to tell jQuery to avoid them.
Rather than the typical document ready setup that you normally put your jQuery code in:
$(document).ready(function() {
// Stuff to do as soon as the DOM is ready;
});
You will instead wrap your jQuery code in this:
jQuery(document).ready(function($){
// Stuff to do as soon as the DOM is ready;
});
You can read more about handling javascript library conflicts here: http://docs.jquery.com/Using_jQuery_with_Other_Libraries

How to iterate over an array with HAML?

I have this in a HAML layout (layout.haml)
- #fonts.each do |font|
%link{:href=>"//fonts.googleapis.com/css?family={font}",:rel=>"stylesheet",:type=>"text/css"}
And I have this in the HAML template index.html.haml
- #fonts = ['Lato:400,300,100','Droid+Serif:700,400'];
When I compile, I get this:
<link href='//fonts.googleapis.com/css?family={font}' rel='stylesheet' type='text/css' />
<link href='//fonts.googleapis.com/css?family={font}' rel='stylesheet' type='text/css' />
What am I doing wrong?
You forgot the hash symbol.
- #fonts.each do |font|
%link{:href=>"//fonts.googleapis.com/css?family=#{font}",:rel=>"stylesheet",:type=>"text/css"}
^ here

Resources