/** * Phoebe DOM Implementation. * * This is a C++ approximation of the W3C DOM model, which follows * fairly closely the specifications in the various .idl files, copies of * which are provided for reference. Most important is this one: * * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html * * Authors: * Bob Jamison * * Copyright (C) 2005 Bob Jamison * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ typedef struct { char *xpathStr; char *desc; char *xml; } XpathTest; XpathTest xpathTests[] = { { "/AAA", "Select the root element AAA", " " " " " " " " " " " " " " " " " " " " }, { "/AAA/CCC", "Select all elements CCC which are children of the root element AAA", " " " " " " " " " " " " " " " " " " " " }, { "/AAA/DDD/BBB", "Select all elements BBB which are children of DDD which are children of the root element AAA", " " " " " " " " " " " " " " " " " " " " "//BBB", }, { "Select all elements BBB", " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//DDD/BBB", "Select all elements BBB which are children of DDD", " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/CCC/DDD/*", "Select all elements enclosed by elements /AAA/CCC/DDD", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/*/*/*/BBB", "Select all elements BBB which have 3 ancestors", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//*", "Select all elements", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/BBB[1]", "Select the first BBB child of element AAA", " " " " " " " " " " " " }, { "/AAA/BBB[last()]", "Select the last BBB child of element AAA", " " " " " " " " " " " " }, { "//@id", "Select all attributes @id", " " " " " " " " " " " " }, { "//BBB[@id]", "Select BBB elements which have attribute id", " " " " " " " " " " " " }, { "//BBB[@name]", "Select BBB elements which have attribute name", " " " " " " " " " " " " }, { "//BBB[@*]", "Select BBB elements which have any attribute", " " " " " " " " " " " " }, { "//BBB[not(@*)]", "Select BBB elements without an attribute", " " " " " " " " " " " " }, { "//BBB[@id='b1']", "Select BBB elements which have attribute id with value b1", " " " " " " " " " " }, { "//BBB[@name='bbb']", "Select BBB elements which have attribute name with value 'bbb'", " " " " " " " " " " }, { "//BBB[normalize-space(@name)='bbb']", "Select BBB elements which have attribute name with value bbb, leading and trailing spaces are removed before comparison", " " " " " " " " " " }, { "//*[count(BBB)=2]", "Select elements which have two children BBB", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//*[count(*)=2]", "Select elements which have 2 children", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//*[count(*)=3]", "Select elements which have 3 children", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//*[name()='BBB']", "Select all elements with name BBB, equivalent with //BBB", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//*[starts-with(name(),'B')]", "Select all elements name of which starts with letter B", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//*[contains(name(),'C')]", "Select all elements name of which contain letter C", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//*[string-length(name()) = 3]", "Select elements with three-letter name", " " " " " " " " " " " " " " " " }, { "//*[string-length(name()) < 3]", "Select elements name of which has one or two characters", " " " " " " " " " " " " " " " " }, { "//*[string-length(name()) > 3]", "Select elements with name longer than three characters", " " " " " " " " " " " " " " " " }, { "//CCC | //BBB", "Select all elements CCC and BBB", " " " " " " " " " " " " " " " " }, { "/AAA/EEE | //BBB", "Select all elements BBB and elements EEE which are children of root element AAA", " " " " " " " " " " " " " " " " }, { "/AAA/EEE | //DDD/CCC | /AAA | //BBB", "Number of combinations is not restricted", " " " " " " " " " " " " " " " " }, { "/AAA", "Equivalent of /child::AAA", " " " " " " " " }, { "/child::AAA", "Equivalent of /AAA", " " " " " " " " }, { "/AAA/BBB", "Equivalent of /child::AAA/child::BBB", " " " " " " " " }, { "/child::AAA/child::BBB", "Equivalent of /AAA/BBB", " " " " " " " " }, { "/child::AAA/BBB", "Both possibilities can be combined", " " " " " " " " }, { "/descendant::*", "Select all descendants of document root and therefore all elements", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/BBB/descendant::*", "Select all descendants of /AAA/BBB", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//CCC/descendant::*", "Select all elements which have CCC among its ancestors", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//CCC/descendant::DDD", "Select elements DDD which have CCC among its ancestors", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//DDD/parent::*", "Select all parents of DDD element", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/BBB/DDD/CCC/EEE/ancestor::*", "Select all elements given in this absolute path", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//FFF/ancestor::*", "Select ancestors of FFF element", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/BBB/following-sibling::*", "The following-sibling axis contains all the following siblings of the context node.", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//CCC/following-sibling::*", "The following-sibling axis contains all the following siblings of the context node.", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/XXX/preceding-sibling::*", "The preceding-sibling axis contains all the preceding siblings of the context node.", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//CCC/preceding-sibling::*", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/XXX/following::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//ZZZ/following::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/XXX/preceding::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//GGG/preceding::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/XXX/descendant-or-self::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//CCC/descendant-or-self::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "/AAA/XXX/DDD/EEE/ancestor-or-self::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//GGG/ancestor-or-self::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//GGG/ancestor::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//GGG/descendant::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//GGG/following::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//GGG/preceding::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//GGG/self::*", "Description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//GGG/ancestor::* | //GGG/descendant::* | //GGG/following::* | //GGG/preceding::* | //GGG/self::*", "description", " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//BBB[position() mod 2 = 0 ]", "Select even BBB elements", " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//BBB[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]", "Select middle BBB element(s)", " " " " " " " " " " " " " " " " " " " " " " " " " " }, { "//CCC[ position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5) ]", "Select middle CCC element(s)", " " " " " " " " " " " " " " " " " " " " " " " " " " } }; //end