xmlmodeltestcase.java

来自「JXPath」· Java 代码 · 共 800 行 · 第 1/2 页

JAVA
800
字号
/*
 * Copyright 1999-2004 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.jxpath.ri.model;

import org.apache.commons.jxpath.AbstractFactory;
import org.apache.commons.jxpath.IdentityManager;
import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathException;
import org.apache.commons.jxpath.JXPathTestCase;
import org.apache.commons.jxpath.Pointer;
import org.apache.commons.jxpath.Variables;
import org.apache.commons.jxpath.xml.DocumentContainer;

/**
 * Abstract superclass for pure XPath 1.0.  Subclasses
 * apply the same XPaths to contexts using different models:
 * DOM, JDOM etc.
 *
 * @author Dmitri Plotnikov
 * @version $Revision: 1.23 $ $Date: 2004/06/30 00:29:13 $
 */

public abstract class XMLModelTestCase extends JXPathTestCase {
    protected JXPathContext context;

    /**
     * Construct a new instance of this test case.
     *
     * @param name Name of the test case
     */
    public XMLModelTestCase(String name) {
        super(name);
    }

    public void setUp() {
        if (context == null) {
            DocumentContainer docCtr = createDocumentContainer();
            context = createContext();
            Variables vars = context.getVariables();
            vars.declareVariable("document", docCtr.getValue());
            vars.declareVariable("container", docCtr);
            vars.declareVariable(
                "element",
                context.getPointer("vendor/location/address/street").getNode());
        }
    }

    protected abstract String getModel();

    protected DocumentContainer createDocumentContainer() {
        return new DocumentContainer(
                JXPathTestCase.class.getResource("Vendor.xml"),
                getModel());
    }
    
    protected abstract AbstractFactory getAbstractFactory();
        
    protected JXPathContext createContext() {
        JXPathContext context =
            JXPathContext.newContext(createDocumentContainer());
        context.setFactory(getAbstractFactory());
        context.registerNamespace("product", "productNS");
        return context;
    }

    /**
     * An XML signature is used to determine if we have the right result
     * after a modification of XML by JXPath.  It is basically a piece
     * of simplified XML.
     */
    protected abstract String getXMLSignature(
        Object node,
        boolean elements,
        boolean attributes,
        boolean text,
        boolean pi);

    protected void assertXMLSignature(
        JXPathContext context,
        String path,
        String signature,
        boolean elements,
        boolean attributes,
        boolean text,
        boolean pi) 
    {
        Object node = context.getPointer(path).getNode();
        String sig = getXMLSignature(node, elements, attributes, text, pi);
        assertEquals("XML Signature mismatch: ", signature, sig);
    }

    // ------------------------------------------------ Individual Test Methods

    public void testDocumentOrder() {
        assertDocumentOrder(
            context,
            "vendor/location",
            "vendor/location/address/street",
            -1);

        assertDocumentOrder(
            context,
            "vendor/location[@id = '100']",
            "vendor/location[@id = '101']",
            -1);

        assertDocumentOrder(
            context,
            "vendor//price:amount",
            "vendor/location",
            1);
    }
    

    public void testSetValue() {
        assertXPathSetValue(
            context,
            "vendor/location[@id = '100']",
            "New Text");

        assertXMLSignature(
            context,
            "vendor/location[@id = '100']",
            "<E>New Text</E>",
            false,
            false,
            true,
            false);

        assertXPathSetValue(
            context,
            "vendor/location[@id = '101']",
            "Replacement Text");

        assertXMLSignature(
            context,
            "vendor/location[@id = '101']",
            "<E>Replacement Text</E>",
            false,
            false,
            true,
            false);
    }

    /**
     * Test JXPathContext.createPath() with various arguments
     */
    public void testCreatePath() {
        // Create a DOM element
        assertXPathCreatePath(
            context,
            "/vendor[1]/location[3]",
            "",
            "/vendor[1]/location[3]");

        // Create a DOM element with contents
        assertXPathCreatePath(
            context,
            "/vendor[1]/location[3]/address/street",
            "",
            "/vendor[1]/location[3]/address[1]/street[1]");

        // Create a DOM attribute
        assertXPathCreatePath(
            context,
            "/vendor[1]/location[2]/@manager",
            "",
            "/vendor[1]/location[2]/@manager");

        assertXPathCreatePath(
            context,
            "/vendor[1]/location[1]/@name",
            "local",
            "/vendor[1]/location[1]/@name");

         assertXPathCreatePathAndSetValue(
            context,
            "/vendor[1]/location[4]/@manager",
            "",
            "/vendor[1]/location[4]/@manager");
         
         context.registerNamespace("price", "priceNS");
         
         // Create a DOM element
         assertXPathCreatePath(
             context,
             "/vendor[1]/price:foo/price:bar",
             "",
             "/vendor[1]/price:foo[1]/price:bar[1]");
    }

    /**
     * Test JXPath.createPathAndSetValue() with various arguments
     */
    public void testCreatePathAndSetValue() {
        // Create a XML element
        assertXPathCreatePathAndSetValue(
            context,
            "vendor/location[3]",
            "",
            "/vendor[1]/location[3]");

        // Create a DOM element with contents
        assertXPathCreatePathAndSetValue(
            context,
            "vendor/location[3]/address/street",
            "Lemon Circle",
            "/vendor[1]/location[3]/address[1]/street[1]");

        // Create an attribute
        assertXPathCreatePathAndSetValue(
            context,
            "vendor/location[2]/@manager",
            "John Doe",
            "/vendor[1]/location[2]/@manager");

        assertXPathCreatePathAndSetValue(
            context,
            "vendor/location[1]/@manager",
            "John Doe",
            "/vendor[1]/location[1]/@manager");
        
        assertXPathCreatePathAndSetValue(
            context,
            "/vendor[1]/location[4]/@manager",
            "James Dow",
            "/vendor[1]/location[4]/@manager");
        
        assertXPathCreatePathAndSetValue(
            context,
            "vendor/product/product:name/attribute::price:language",
            "English",
            "/vendor[1]/product[1]/product:name[1]/@price:language");
        
        context.registerNamespace("price", "priceNS");
        
        // Create a DOM element
        assertXPathCreatePathAndSetValue(
            context,
            "/vendor[1]/price:foo/price:bar",
            "123.20",
            "/vendor[1]/price:foo[1]/price:bar[1]");
    }

    /**
     * Test JXPathContext.removePath() with various arguments
     */
    public void testRemovePath() {
        // Remove XML nodes
        context.removePath("vendor/location[@id = '101']//street/text()");
        assertEquals(
            "Remove DOM text",
            "",
            context.getValue("vendor/location[@id = '101']//street"));

        context.removePath("vendor/location[@id = '101']//street");
        assertEquals(
            "Remove DOM element",
            new Double(0),
            context.getValue("count(vendor/location[@id = '101']//street)"));

        context.removePath("vendor/location[@id = '100']/@name");
        assertEquals(
            "Remove DOM attribute",
            new Double(0),
            context.getValue("count(vendor/location[@id = '100']/@name)"));
    }

    public void testID() {
        context.setIdentityManager(new IdentityManager() {
            public Pointer getPointerByID(JXPathContext context, String id) {
                NodePointer ptr = (NodePointer) context.getPointer("/");
                ptr = ptr.getValuePointer(); // Unwrap the container
                return ptr.getPointerByID(context, id);
            }
        });

        assertXPathValueAndPointer(
            context,
            "id(101)//street",
            "Tangerine Drive",
            "id('101')/address[1]/street[1]");

        assertXPathPointerLenient(
            context,
            "id(105)/address/street",
            "id(105)/address/street");
    }

    public void testAxisChild() {
        assertXPathValue(
            context,
            "vendor/location/address/street",
            "Orchard Road");

        // child:: - first child does not match, need to search
        assertXPathValue(
            context,
            "vendor/location/address/city",
            "Fruit Market");
        
        // local-name(qualified)
        assertXPathValue(
            context,
            "local-name(vendor/product/price:amount)",
            "amount");
        
        // local-name(non-qualified)
        assertXPathValue(context, "local-name(vendor/location)", "location");

        // name (qualified)
        assertXPathValue(
            context,
            "name(vendor/product/price:amount)",
            "value:amount");

        // name (non-qualified)
        assertXPathValue(
            context,
            "name(vendor/location)",
            "location");

        // namespace-uri (qualified)
        assertXPathValue(
            context,
            "namespace-uri(vendor/product/price:amount)",
            "priceNS");

        // default namespace does not affect search
        assertXPathValue(context, "vendor/product/prix", "934.99");
        
        assertXPathValue(context, "/vendor/contact[@name='jim']", "Jim");
        
        boolean nsv = false;
        try {
            context.setLenient(false);
            context.getValue("/vendor/contact[@name='jane']");
        }
        catch (JXPathException ex) {
            nsv = true;
        }
        assertTrue("No such value: /vendor/contact[@name='jim']", nsv);
                
        nsv = false;
        try {
            context.setLenient(false);
            context.getValue("/vendor/contact[@name='jane']/*");
        }
        catch (JXPathException ex) {
            nsv = true;
        }
        assertTrue("No such value: /vendor/contact[@name='jane']/*", nsv);
        
        // child:: with a wildcard
        assertXPathValue(
            context,
            "count(vendor/product/price:*)",
            new Double(2));

        // child:: with the default namespace
        assertXPathValue(context, "count(vendor/product/*)", new Double(4));

        // child:: with a qualified name
        assertXPathValue(context, "vendor/product/price:amount", "45.95");
    }

    public void testAxisChildIndexPredicate() {
        assertXPathValue(
            context,
            "vendor/location[2]/address/street",
            "Tangerine Drive");
    }

    public void testAxisDescendant() {
        // descendant::
        assertXPathValue(context, "//street", "Orchard Road");

        // descendent:: with a namespace and wildcard
        assertXPathValue(context, "count(//price:*)", new Double(2));

        assertXPathValueIterator(context, "vendor//saleEnds", list("never"));

        assertXPathValueIterator(context, "vendor//promotion", list(""));

        assertXPathValueIterator(
            context,
            "vendor//saleEnds[../@stores = 'all']",

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?