Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

« Newer Snippets
Older Snippets »
Showing 21-30 of 115 total

Tidy with Ruby

Ruby interface to HTML Tidy Library Project (tidy.sf.net).

  require 'tidy'
  Tidy.path = '/usr/lib/libtidy.so'
  html = '<html><title>title</title>Body</html>'
  xml = Tidy.open(:show_warnings=>true) do |tidy|
    tidy.options.output_xml = true
    puts tidy.options.show_warnings
    xml = tidy.clean(html)
    puts tidy.errors
    puts tidy.diagnostics
    xml
  end
  puts xml


output
true
line 1 column 1 - Warning: missing <!DOCTYPE> declaration
line 1 column 7 - Warning: plain text isn't allowed in <head> elements
Info: Document content looks like XHTML 1.0 Transitional
2 warnings, 0 errors were found!

<html>
<head>
<meta name="generator"
content="HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" />
<title>title</title>
</head>
<body>Body</body>
</html>



Note: Couldn't get it to run on Ubuntu version 7.10 or 7.04 (LoadError: no such file to load -- tidy
), however it ran fine on Gentoo.

reference: http://tidy.rubyforge.org/

*update 18-Mar-08 16:15*
I got it working on Ubuntu I simply needed to add - require 'rubygems'

Encode simple passwords

This code was used to demonstrate how to translate easy to remember simple (weak) passwords into more difficult to guess (strong) passwords. Example: Using Gmail I like an easy to remember password, I submit the password 'jr123' to the password_lookup.html page and what's returned to me is a stronger password 'NCC2SI1T'.

file: passwd_lookup.rb (generates an xml file containing an alphanumeric index with corresponding cryptic values)
class PasswordLookup

  def initialize()
    chars =  (0..9).to_a  + Array.new(7) + ('A'..'Z').to_a + Array.new(6) + ('a'..'z').to_a 
    @chars = (0..9).to_a  + ('A'..'Z').to_a + ('a'..'z').to_a 
    @doc = Document.new()
    root = Element.new('codes')
    @doc.add_element(root)

    chars.each do |char|
      node = Element.new('code')
      if not char.nil? 
        node.attributes['index'] = char
        node.attributes['value'] = get_random_chars(2)
      end
      root.add_element(node)
    end
    puts root
  end

  
  def save(filepath)
    file = File.new(filepath,'w')
    file.puts @doc
    file.close
  end
        
  def get_random_chars(vword_size)
    newpass = Array.new(rand(vword_size) + 1, '').collect{@chars[rand(@chars.size)]}.join
    # return the encryption providing it doesn't already exist in the lookup table.
    if not /value=\'#{newpass}\'/.match @doc.root.elements.to_a.to_s 
     return newpass 
    else
     return get_random_chars(vword_size) 
    end

  end
  
  private :get_random_chars
  
end


output extract: (codes - see also http://rorbuilder.info/pl/codes)
<codes>
<code value='4h' index='a'/><code value='B' index='b'/><code value='m' index='c'/>
<code value='qf' index='d'/>
</codes>


file: password_lookup.js
var t;
var m_doc;

function loadXml() {
  url = 'http://rorbuilder.info/pl/codes';
  m_doc = XML.load(url);
}

function getCode(val,i) {
  pos = val.charCodeAt(i) - 48;
  node = m_doc.documentElement.childNodes[pos]
  return node.getAttribute('value');
}

function timed_update(keyCode,  val) {
  if (val.length > 0 && ((keyCode > 40) || (keyCode == 8)) ) {
    clearTimeout(t);
    t = setTimeout("revealCode('" + val + "')", 1000);
  }
  else
  {  
    o = document.getElementById('out1');
    if (val.length <= 0 && o.value.length > 0) {
      o.value = '';
    }
  }
  
}

function revealCode(val) {
  var iEnd = val.length;
  var newcode = '';
  for (i=0;i<iEnd;i++) {
      
    var codex = getCode(val,i);
    newcode += codex;
  }
  update(newcode);
}

function update(val){
  o = document.getElementById('out1');
  o.value = val;
  /*var o_copied = document.getElementById('out1').createTextRange();
  o_copied.exeCommand("Copy");*/
}


file: password_lookup.html
  <body onload="loadXml()">
    <h1>Password lookup</h1>
    <dl>
    <dt><label for="in1">Enter password:</label></dt>    
    <dd><input type="text" name="in1" id="in1" value="" 
  onkeyup="timed_update(event.keyCode, this.value)" /></dd>
    
    <dt><label for="out1">Generated password</label></dt>
    <dd><input type="text" name="out1" id="out1" value=""/></dd>
    <dd><input type="button" name="clear1" id="clear1" onclick="clearPassword()" value="clear"/></dd>

    </dl>
    <p>see also: <a href="codes.xml" title="password code lookup table">codes.xml</a></p>
  </body>


Try out the encode a simple password demo [rorbuilder.info].

see also: Reading an XML file usng JavaScript [snippets.dzone.com]

Using XPath in JavaScript (Mozilla based)

The following JavaScript code uses XPath to select a specific element. Note: This code works for Firefox, but Internet Explorer has it's own implementation of XPath. see Introduction to using XPath in JavaScript [mozilla.org]

doc (xml document)
<codes>
  <codex value='bQ' index='Q'/>
  <codex value='S' index='R'/>
  <codex value='PU' index='S'/>
  <codex value='ji' index='T'/>
  <codex value='0' index='U'/>
  <codex value='33' index='V'/>
  <codex value='A' index='W'/>
  <codex value='tO' index='X'/>
  <codex value='fW' index='Y'/>
  <codex value='P' index='Z'/>
  <codex value='4h' index='a'/>
  <codex value='B' index='b'/>
  <codex value='m' index='c'/>
  <codex value='qf' index='d'/>
  <codex value='uJ' index='e'/>
</codes>


Assuming the doc object below contains the XML data from above.
var nodesSnapshot = doc.evaluate("codes/codex[@index='a']", doc, null, XPathResult.
  UNORDERED_NODE_SNAPSHOT_TYPE, null );
node = nodesSnapshot.snapshotItem(0);
msg = "The secret code for '" + node.getAttribute('index') + "' is " + node.getAttribute('value');
alert(msg);


output (value from the alert box)
"The secret code for 'a' is 4h"


see also: Reading an XML file using JavaScript

Retrieve your Gmail messages as an XML feed

This Ruby example shows how to retrieve your most recent email as an atom XML feed from the Google Apps website.

require 'rubygems'
require 'httpclient'

url = "https://mail.google.com/a/yourwebsite.com/feed/atom"
client = HTTPClient.new
client.debug_dev = STDOUT if $DEBUG
client.set_auth(url, 'yourname@yourwebsite.com', 'yourpassword')
resp = client.get(url)


Note: You might require to gem install httpclient.

Reading an XML file using JavaScript

Reads an xml file using JavaScript from a web page. Files used: loadxml.js (main script), readxml.js (client script), and readxml.html. The code for loadxml.js was copied from the article JavaScript and XML [devarticles.com]

file: loadxml.js
  XML.load = function(url) {
    var xmldoc = XML.newDocument();
    xmldoc.async = false;  
    xmldoc.load(url);
    return xmldoc;  
  };


XML.newDocument = function(rootTagName, namespaceURL) {
    if (!rootTagName) rootTagName = "";
    if (!namespaceURL) namespaceURL = "";

    if (document.implementation && document.implementation.createDocument) {
        // This is the W3C standard way to do it
        return document.implementation.createDocument(namespaceURL, 
                       rootTagName, null);
    }
    else { // This is the IE way to do it
        // Create an empty document as an ActiveX object
        // If there is no root element, this is all we have to do
        var doc = new ActiveXObject("MSXML2.DOMDocument");

        // If there is a root tag, initialize the document
        if (rootTagName) {
            // Look for a namespace prefix
            var prefix = "";
            var tagname = rootTagName;
            var p = rootTagName.indexOf(':');
            if (p != -1) {
                prefix = rootTagName.substring(0, p);
                tagname = rootTagName.substring(p+1);
            }

            // If we have a namespace, we must have a namespace prefix
            // If we don't have a namespace, we discard any prefix
            if (namespaceURL) {
                if (!prefix) prefix = "a0"; // What Firefox uses
            }
            else prefix = "";

            // Create the root element (with optional namespace) as a
            // string of text
            var text = "<" + (prefix?(prefix+":"):"") + tagname +
                (namespaceURL
                 ?(" xmlns:" + prefix + '="' + namespaceURL +'"')
                 :"") +
                "/>";
            // And parse that text into the empty document
            doc.loadXML(text);
        }
        return doc;
    }
}; 


file: readxml.js
function readXmlFile() {
  url = 'http://rorbuilder.info/pl/test123';

  doc = XML.load(url);
  alert(doc.documentElement.firstChild.nextSibling.firstChild.nodeValue);
}


file: readxml.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Read an XML file</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <script type="text/javascript" src="js/loadxml.js"/>
    <script type="text/javascript" src="js/readxml.js"/>
  </head>

  <body>
    <h1>ReadXML</h1>
    <p>
       If all goes well you should see an alert box display the message 'testing 123'
   </p>
    <p>Press the 'go' button to read the xml file '<a href="test123">test123</a>' 
       from the web server. 
       <input type="button" onclick="readXmlFile()" value="go"/>
    </p>

    
  </body>
</html>


Note: To avoid the cross-site security error message 'permission denied', store all the files on the same web server.

To test the above code try out the demo to read the xml file [rorbuilder.info].

Transforming XML into RSS

Using the previous code snippet which prepared an XML file it can now be transformed to RSS using the XSL below.


file: gang2rss.xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

	<xsl:output method="xml" encoding="iso-8859-1" indent="yes"  />

	<xsl:template match="rss">

		<rss version="2.0">	
		<channel>
		<title>The Gang</title>
		<link>http://newsgang.net/audio/</link>
		<description>The Gang podcast</description>

  	<language>en</language>

	<xsl:apply-templates select="item" />

		</channel>
		</rss>

	</xsl:template>

	<xsl:template match="item">

	<item>
		<title><xsl:value-of select="title"/></title>
		<link>http://newsgang.net<xsl:value-of select="href"/></link>
		<description><xsl:value-of select="date"/></description>
		<enclosure>http://newsgang.net<xsl:value-of select="href_audio"/></enclosure>
	</item>

	</xsl:template>	

</xsl:stylesheet>


To transform the xsl file from the command-line you would type:

xsltproc gang2rss.xsl thegang_rss.xml

output
<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
  <channel>
    <title>The Gang</title>
    <link>http://newsgang.net/audio/</link>
    <description>The Gang podcast</description>
    <language>en</language>
    <item>
      <title>TheGangXII-II</title>
      <link>http://newsgang.net/gangitem/id=6501</link>
      <description>Jan 25</description>
      <enclosure>http://newsgang.net/gangitem/id=6501&amp;from=audio</enclosure>
    </item>
    <item>
      <title>TheGangXII-I</title>
      <link>http://newsgang.net/gangitem/id=6499</link>
      <description>Jan 25</description>
      <enclosure>http://newsgang.net/gangitem/id=6499&amp;from=audio</enclosure>
    </item>
    <item>
      <title>NewsGangLive01.24.08</title>
      <link>http://newsgang.net/gangitem/id=6445</link>
      <description>Jan 24</description>
      <enclosure>http://newsgang.net/gangitem/id=6445&amp;from=audio</enclosure>
    </item>
    <item>
      <title>NewsGangLiveII</title>
      <link>http://newsgang.net/gangitem/id=6377</link>
      <description>Jan 23</description>
      <enclosure>http://newsgang.net/gangitem/id=6377&amp;from=audio</enclosure>
    </item>
  </channel>
</rss>

Note: The enclosure url in this example does not reference the media file directly.

see also: http://en.wikipedia.org/wiki/RSS_(file_format)

Outputting XML as text within XML

Return XML from the web server, and make the XML with result tags simple text. Using HTTP.responseXML the result xmldoc.documentElement.firstChild.nodeValue was then passed into a textarea.

require 'cgi'

cgi = CGI.new

puts "Content-Type: text/xml"
puts

print "<result>"
print "<![CDATA[<a>123</a>]]>" 
print "</result>"


Using the XSLT sum function

This XML and XSLT code is an example of storing and displaying a car mileage log. Notably the XSLT sum() function displays the total no of miles.


file: car_log.xsl
<?xml version="1.0"?>

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      
    <xsl:template match="car_log">
      <div>      
        <p>Total miles this month: <xsl:value-of select="sum(records/entry/miles)" /></p>
        <xsl:apply-templates select="records"/>
      </div>
    </xsl:template>
    
    <xsl:template match="car_log/records/entry"><xsl:variable name="pos" select="position()"/>
    <div class="record">
      <dl>
        <dt><label for="trip"><xsl:value-of select="@title"/>trip</label></dt>
        <dd>
          <input type="text" id="trip{$pos}" name="trip{$pos}" value="{trip}" size="{@size}" />
        </dd>
          
        <dt><label for="miles"><xsl:value-of select="@title"/>miles</label></dt>
        <dd>
          <input type="text" id="miles{$pos}" name="miles{$pos}" value="{miles}" size="2" />
        </dd>
          
        <dt><label for="description"><xsl:value-of select="@title"/>description</label></dt>
        <dd>
          <input type="text" id="description{$pos}" name="description{$pos}" value="{description}"  />
        </dd>        
      </dl>
    </div>
    </xsl:template>
    </xsl:stylesheet>

file: car_log.xml
<car_log>
  <summary>
    <project>car_log</project>
  </summary>
  <records>
    <entry id='17962'><date>Wed Dec 12 20:00:33 +0000 2007</date><trip>trip to the supermarket</trip><miles>11.8</miles><description>my first trip with the GPS installed</description></entry>
    <entry id='18024'><date>Fri Dec 14 11:45:09 +0000 2007</date><trip>driving around the park</trip><miles>26.1</miles><description/></entry>
    <entry id='18173'><date>Thu Dec 20 01:21:27 +0000 2007</date><trip>trip to the supermarket</trip><miles> 8.5</miles><description/></entry>
    <entry id='18174'><date>Thu Dec 20 01:34:26 +0000 2007</date><trip>visiting parents</trip><miles>12.7</miles><description/>
    </entry>
  </records>
</car_log>

output
Total miles this month: 59.1
...

Setting a string variable with a mult-line text value

This example demonstrates how easy it is to copy and paste human-readable text from elsewhere and declare it as a string in your code.

string = <<RUBY_RUBY_RUBY
  <mydoc>
    <someelement attribute="nanoo">Text, text, text</someelement>
  </mydoc>
RUBY_RUBY_RUBY



Note: Remember to encase the text within a pair of strings, any string (the convention is to make it uppercase) and ensure it's not a reserved keyword, or a variable declared already.

Pretty Print XML using Ruby

This code makes the XML output look pretty. I tried using the documentation from the REXML website to apply the method example doc.write($stdout,0), but I gave up, and instead wrote my own XML pretty-print method.

require 'rexml/document'
include REXML

  def pretty_print(parent_node, itab)
    buffer = ''

    parent_node.elements.each do |node|

      buffer += ' ' * itab + "<#{node.name}#{get_att_list(node)}"
  
      if node.to_a.length > 0
        buffer += ">"
        if node.text.nil?
          buffer += "\n"
          buffer += pretty_print(node,itab+2) 
          buffer += ' ' * itab + "</#{node.name}>\n"
        else
          node_text = node.text.strip
          if node_text != ''
            buffer += node_text 
            buffer += "</#{node.name}>\n"        
          else
            buffer += "\n" + pretty_print(node,itab+2) 
            buffer += ' ' * itab + "</#{node.name}>\n"        
          end
        end
      else
        buffer += "/>\n"
      end
      
    end
    buffer
  end

  def get_att_list(node)
    att_list = ''
    node.attributes.each { |attribute, val| att_list += " #{attribute}='#{val}'" }
    att_list
  end
  
  def pretty_xml(doc)
    buffer = ''
    xml_declaration = doc.to_s.match('<\?.*\?>').to_s
    buffer += "#{xml_declaration}\n" if not xml_declaration.nil?
    xml_doctype = doc.to_s.match('<\!.*\">').to_s
    buffer += "#{xml_doctype}\n" if not xml_doctype.nil?
    buffer += "<#{doc.root.name}#{get_att_list(doc.root)}"
    if doc.root.to_a.length > 0
      buffer +=">\n#{pretty_print(doc.root,2)}</#{doc.root.name}>"
    else
      buffer += "/>\n"
    end
  end

xml_data = "<hi id='124'><yo><a id='1'/><b/><c/></yo><sushi><love>Ruby</love></sushi></hi>"
doc = Document.new(xml_data)
pretty_xml(doc)


output
<hi id='124'>
  <yo>
    <a id='1'/>
    <b/>
    <c/>
  </yo>
  <sushi>
    <love>Ruby</love>
  </sushi>
</hi>


*Update 7-Jan-08 1:51AM *
Although I haven't tried running the following XSL code, this might actually have been a better solution to my problem. source: http://www.printk.net/~bds/indent.html

*Pretty Print XML using XSLT*
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="ISO-8859-1"/>
  <xsl:param name="indent-increment" select="'   '"/>
  
  <xsl:template name="newline">
    <xsl:text disable-output-escaping="yes">
</xsl:text>
  </xsl:template>
  
  <xsl:template match="comment() | processing-instruction()">
    <xsl:param name="indent" select="''"/>
    <xsl:call-template name="newline"/>    
    <xsl:value-of select="$indent"/>
    <xsl:copy />
  </xsl:template>
  
  <xsl:template match="text()">
    <xsl:param name="indent" select="''"/>
    <xsl:call-template name="newline"/>    
    <xsl:value-of select="$indent"/>
    <xsl:value-of select="normalize-space(.)"/>
  </xsl:template>
    
  <xsl:template match="text()[normalize-space(.)='']"/>
  
  <xsl:template match="*">
    <xsl:param name="indent" select="''"/>
    <xsl:call-template name="newline"/>    
    <xsl:value-of select="$indent"/>
      <xsl:choose>
       <xsl:when test="count(child::*) > 0">
        <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates select="*|text()">
           <xsl:with-param name="indent" select="concat ($indent, $indent-increment)"/>
         </xsl:apply-templates>
         <xsl:call-template name="newline"/>
         <xsl:value-of select="$indent"/>
        </xsl:copy>
       </xsl:when>       
       <xsl:otherwise>
        <xsl:copy-of select="."/>
       </xsl:otherwise>
     </xsl:choose>
  </xsl:template>    
</xsl:stylesheet>
« Newer Snippets
Older Snippets »
Showing 21-30 of 115 total