Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   * Copyright (c) 2011 Mozilla Foundation
   * Permission is hereby granted, free of charge, to any person obtaining a 
   * copy of this software and associated documentation files (the "Software"), 
   * to deal in the Software without restriction, including without limitation 
   * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
   * and/or sell copies of the Software, and to permit persons to whom the 
   * Software is furnished to do so, subject to the following conditions:
  * The above copyright notice and this permission notice shall be included in 
  * all copies or substantial portions of the Software.
 package org.whattf.checker;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
Checker for microdata constraints that require tree traversal. The SAX events are used to construct a minimal tree with only the relevant elements and attributes, which is then validated. The followings constraints are supported: - The itemref attribute, if specified, must have a value that is an unordered set of unique space-separated tokens that are case-sensitive, consisting of IDs of elements in the same home subtree. - A document must not contain any items for which the algorithm to find the properties of an item finds any microdata errors. - All itemref attributes in a Document must be such that there are no cycles in the graph formed from representing each item in the Document as a node in the graph and each property of an item whose value is another item as an edge in the graph connecting those two items. - A document must not contain any elements that have an itemprop attribute that would not be found to be a property of any of the items in that document were their properties all to be determined Not all checks are unconditional. For example, the itemref constraints are only checked if the itemscope attribute is present. However, the checks are chained such that if a document validates with no errors, then all the constraints are satisfied.
 public class MicrodataChecker extends Checker {
The relevant aspects of an HTML element. There is no Document class as there is no need for a root element from which all Elements can be reached.
     class Element {
         public final Locator locator;
         public final String[] itemProp;
         public final String[] itemRef;
         public final boolean itemScope;
         public final List<Elementchildren;
         // tree order of the element, for cheap sorting and hashing
         private final int order;
         public Element(Locator locatorString[] itemPropString[] itemRefboolean itemScope) {
             this. = locator;
             this. = itemProp;
             this. = itemRef;
             this. = itemScope;
             this. = new LinkedList<Element>();
             this. = ++;
         @Override public boolean equals(Object that) {
             return this == that;
        @Override public int hashCode() {
            return ;

Helper for building the Element tree(s).
        class Builder {
            public final Builder parent;
            public final int depth// nesting depth in the input
            public Builder(Builder parentint depth) {
                this. = parent;
                this. = depth;
            public void appendChild(Element elm) {
    private int depth// nesting depth in the input
    private Element.Builder builder;
    private static int counter;
    // top-level items (itemscope but not itemprop)
    private List<Elementitems;
    // property elements (itemprop)
    private Set<Elementproperties;
    // mapping from id to Element (like getElementById)
    private Map<StringElementidmap;
    private Locator locator;


See also:
    public void reset() {
         = 0;
         = null;
         = 0;
         = new LinkedList<Element>();
         = new LinkedHashSet<Element>();
         = new HashMap<StringElement>();

    public void startElement(String uriString localNameString qNameAttributes attsthrows SAXException {
        if ("" != uri) {
        String id = null;
        String[] itemProp = null;
        String[] itemRef = null;
        boolean itemScope = false;
        int len = atts.getLength();
        for (int i = 0; i < leni++) {
            if (atts.getURI(i).isEmpty()) {
                String attLocal = atts.getLocalName(i);
                String attValue = atts.getValue(i);
                if ("id" == attLocal) {
                    id = attValue;
                } else if ("itemprop" == attLocal) {
                    itemProp = AttributeUtil.split(attValue);
                } else if ("itemref" == attLocal) {
                    itemRef = AttributeUtil.split(attValue);
                } else if ("itemscope" == attLocal) {
                    itemScope = true;
        if (id != null || itemProp != null || itemScope == true) {
            Element elm = new Element(new LocatorImpl(), itemPropitemRefitemScope);
            if (itemProp != null) {
            } else if (itemScope) {
            if (!.containsKey(id)) {
            if ( != null) {
             = Builder();

    public void endElement(String uriString localNameString qNamethrows SAXException {
        if ( != null && . == ) {
             = .;

    public void endDocument() throws SAXException {
        // check all top-level items
        for (Element item : ) {
            checkItem(itemnew ArrayDeque<Element>());
        // emit errors for unreferenced properties
        for (Element prop : ) {
            err("The \u201Citemprop\u201D attribute was specified, but the element is not a property of any item."prop.locator);

Check itemref constraints. This mirrors the "the properties of an item" algorithm, modified to recursively check sub-items.
    private void checkItem(Element rootDeque<Elementparentsthrows SAXException {
        Deque<Elementpending = new ArrayDeque<Element>();
        Set<Elementmemory = new HashSet<Element>();
        for (Element child : root.children) {
        if (root.itemRef != null) {
            for (String id : root.itemRef) {
                Element refElm = .get(id);
                if (refElm != null) {
                } else {
                    err("The \u201Citemref\u201D attribute referenced \u201C" + id + "\u201D, but there is no element with an \u201Cid\u201D attribute with that value."root.locator);
        boolean memoryError = false;
        while (pending.size() > 0) {
            Element current = pending.pop();
            if (memory.contains(current)) {
                memoryError = true;
            if (!current.itemScope) {
                for (Element child : current.children) {
            if (current.itemProp != null) {
                if (current.itemScope) {
                    if (!parents.contains(current)) {
                    } else {
                        err("The \u201Citemref\u201D attribute created a circular reference with another item."current.locator);
        if (memoryError) {
            err("The \u201Citemref\u201D attribute contained redundant references."root.locator);

    public void setDocumentLocator(Locator locator) {
        this. = locator;
New to GrepCode? Check out our FAQ X