January 1, 2012

Pure CSS Navigation Bar with No Image Files or JavaScript

A navigation bar styled purely with CSS is easier to modify and reuse than one dependent on image files or JavaScript.

Pure CSS Navigation Bar

HTML for a navigation bar (a flat menu bar also called a nav bar or link bar) should contain just the list of buttons with their respective links.

<ul class=navigation-bar>
   <li><a href="#a">Alligator</a></li>
   <li><a href="#b">Bullfrog</a></li>
   <li class=current><a href="#c">Cheetah</a></li>
   <li><a href="#d">Dolphin</a></li>
</ul>
Example Navigation Bar HTML

Pure CSS Navigation Bar uses CSS to layout the buttons horizontally by disabling list-style-type and displaying the list items as table-cell elements.

ul.navigation-bar {
   list-style-type: none;
   background-image: -webkit-linear-gradient(top, silver, midnightblue);
   background-image:    -moz-linear-gradient(top, silver, midnightblue);
   background-image:     -ms-linear-gradient(top, silver, midnightblue);
   background-image:         linear-gradient(top, silver, midnightblue);
   border: 2px solid dimgray;
   padding: 0px;
   margin: 0px;
   background-color: midnightblue; /* IE6...IE9 */
   *line-height: 3.2em; /* IE6,IE7 */
   }
ul.navigation-bar li {
   display: table-cell;
   *display: inline; /* IE6,IE7 */
   }
ul.navigation-bar li a {
   display: table-cell;
   text-decoration: none;
   outline: none;
   font-size: 120%;
   color: white;
   border-right: 2px solid dimgray;
   padding: 15px 25px; /* sets button size */
   }
ul.navigation-bar li a:hover {
   background-color: rgba(255, 255, 255, 0.2);
   }
ul.navigation-bar li.current a:hover {
   background-color: rgba(255, 255, 255, 0.0);
   }
Pure CSS Navigation Bar

Try it out:
The color for the navigation bar in the example screenshot is midnightblue.  Other professional looking colors for the navigation bar include firebrick, seagreen, sienna, darkslategray, and dimgray.

Pure CSS Navigation Bar will work on sites that validate to strict HTML or HTML5.  And it follows a progressive enhancement strategy in that the navigation bar will display and function correctly for most all web browsers while providing improved visual effects for standards compliant web browsers.

December 20, 2011

Simple Workaround for Strict HTML Validation of _blank Target

There are times when it's legitimate to automatically open up a link in a new tab or window of the user's web browser.  Setting the link's "target" attribute to "_blank" used to be the correct way to realize this behavior.

<a href="http://www.snapbackup.org/" target="_blank">backup</a>
Obsolete Usage

Partly because the target expresses behavior instead of content, the "target" attribute has been depreciated and does not pass validation for strict HTML or HTML5.  There's a cheap and dirty JavaScript trick that achieves the desired behavior and still validates.

<a href="http://www.snapbackup.org/" onclick="this.target='_blank';">backup</a>
Compact (and valid HTML) Workaround

Example link with "_blank" target:
This workaround does pollute the semantics of the HTML with behavior instructions, but it's compact, easy to understand, and validates.

For sites with jQuery, you can keep the HTML cleaner by using the "rel" attribute to designate external links and then adding targets with a jQuery selector.

February 9, 2010

Minimal Java for XML Processing

XML Logo
These Java examples show very simple ways to write, validate, and read XML files.  Use the examples as tutorials to learn the basics of working with XML.

Catalog of Java examples for XML processing:
Java Get Powered
The examples are presented as complete programs so you can quickly run and test them.

For example, to try out the "XML Writer" program, you would download the XmlWriter.java file and execute the following commands:
     $ javac *.java
     $ java XmlWriter.class
Code here is Public Domain Software — free to use as you like.


XML Writer
This example program creates a very simple DOM (Document Object Model) containing a list of countries and then writes the DOM out to an XML file.

XmlWriter.java
import java.io.File;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;

public class XmlWriter {

   public static void main(String[] args) {
      try {
         //Sample Data (countries and capitals)
         HashMap<String, String> data = new HashMap<String, String>();
         data.put("Egypt",   "Cairo");
         data.put("Finland", "Helsinki");
         data.put("Japan",   "Tokyo");

         //Create DOM (with top-level node)
         DocumentBuilder xmlBuilder =
            DocumentBuilderFactory.newInstance().newDocumentBuilder();
         Document xmlDoc = xmlBuilder.newDocument();
         Node node = xmlDoc.createElement("countries");
         xmlDoc.appendChild(node);  //top-level node

         //Add Data to DOM
         for (String key : data.keySet()) {
            Element elem = xmlDoc.createElement("country");
            elem.setAttribute("capital", data.get(key));   //attrib
            elem.appendChild(xmlDoc.createTextNode(key));  //content
            node.appendChild(elem);
            }

         //Write DOM to XML file
         Source source = new DOMSource(xmlDoc);
         Result result = new StreamResult(new File("countries.xml"));
         Transformer xformer =
            TransformerFactory.newInstance().newTransformer();
         xformer.setOutputProperty(OutputKeys.INDENT, "yes");
         xformer.transform(source, result);
         }
      catch (Exception e) {
         System.out.println(e.getMessage());
         }
      }

   }
View/Download: XmlWriter.java

countries.xml
<?xml version="1.0" encoding="UTF-8"?>
<countries>
<country capital="Helsinki">Finland</country>
<country capital="Cairo">Egypt</country>
<country capital="Tokyo">Japan</country>
</countries>
File Created by Program

Note that using a DOM holds the entire XML tree structure in memory. For large data sets it is often necessary to instead use SAX (Simple API for XML) which uses an event based approach to hold and process only the part of the document that is needed.


XML Validator
This example program validates an XML file against an XSD (XML Schema Definition).

XmlValidator.java
import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.transform.stream.StreamSource;

public class XmlValidator {

   public static void main(String[] args) {
      try {
         StreamSource xsdInput = new StreamSource(new
            XmlValidator().getClass().getResourceAsStream("countries.xsd"));
         Schema schema = SchemaFactory.newInstance(
            XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(xsdInput);
         schema.newValidator().validate(new StreamSource(
            new File("countries.xml")));
         System.out.println("XML file sucessfully validated against XSD.");
         }
      catch (Exception e) {
         System.out.println(e.getMessage());
         }
      }

   }
View/Download: XmlValidator.java

XML Schema Used to Validate XML
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <xs:element name="countries">
      <xs:complexType>
         <xs:sequence>
            <xs:element name="country" maxOccurs="unbounded"/>
            </xs:sequence>
         </xs:complexType>
      </xs:element>
   <xs:element name="country">
      <xs:complexType mixed="true">
         <xs:attribute name="capital" type="xs:string" use="required" />
         </xs:complexType>
      </xs:element>
   </xs:schema>
View/Download: countries.xsd

cvc-complex-type.2.4.a: Invalid content was found starting
with element 'region'. One of '{"":country}' is expected.
Program Output

The above error message was generated from an input file (countries.xml) containing invalid XML.  A <region> tag was used where a <country> tag was expected.


XML Reader
This example program reads an XML file and prints out the name of each node along with its first attribute.

XmlReader.java
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*;

public class XmlReader {

   static void processNode(Node node) {
      String msg = "node --> " + node.getNodeName();
      String nodeContent = node.getFirstChild().getNodeValue();
      if (!nodeContent.equals("\n"))  //check if has text content
         msg = msg + " | value: " + nodeContent; //add text content
      if (node.hasAttributes())  //add first attrib if exists
          msg = msg + " | attrib: " +
            node.getAttributes().item(0).getNodeName() + "=" +
            node.getAttributes().item(0).getNodeValue();
      System.out.println(msg);  //display node information
      for (Node subNode = node.getFirstChild(); subNode != null;
            subNode = subNode.getNextSibling())
         if (subNode.getNodeType() == Node.ELEMENT_NODE)
            processNode(subNode);
      }

   public static void main(String[] args) {
      try {
         DocumentBuilder xmlBuilder =
            DocumentBuilderFactory.newInstance().newDocumentBuilder();
         Document xmlDoc = xmlBuilder.parse(new File("countries.xml"));
         processNode(xmlDoc.getDocumentElement());
         }
      catch (Exception e) {
         System.out.println(e.getMessage());
         }
      }

   }
View/Download: XmlReader.java

node --> countries
node --> country | value: Finland | attrib: capital=Helsinki
node --> country | value: Egypt | attrib: capital=Cairo
node --> country | value: Japan | attrib: capital=Tokyo
Program Output (input file: countries.xml)


Further Reading

Elsewhere: