commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Kristian Mandrup" <krist...@mandrup.dk>
Subject [digester] Patches to xmlrules : NodeCreateRule addon + namespace prefix support
Date Mon, 28 Feb 2005 16:43:09 GMT
Added PREFIX namespace support for NodeCreateRule: Can now parse a XML Schema correctly ☺
Tested (see Junit TestCase below). Works fine!

+++

public class NodeCreateRule extends Rule {

    private class NodeBuilder
        extends DefaultHandler {


+++
        public void startElement(String namespaceURI, String localName,
                                 String qName, Attributes atts)
            throws SAXException {

            try {
                Node previousTop = top;
                if ((localName == null) || (localName.length() == 0)) { 
                    top = doc.createElement(qName);
                } else {
                    top = doc.createElementNS(namespaceURI, localName);
                }
                String prefix = qName.split(":")[0];
                if (prefix != null) {                   
                    top.setPrefix(prefix);
                }
                for (int i = 0; i < atts.getLength(); i++) {
                    Attr attr = null;
                    String attQname = atts.getQName(i);
                    prefix = null;
                    if (attQname.contains(":"))
                        prefix = attQname.split(":")[0];
                    if ((atts.getLocalName(i) == null) ||
                        (atts.getLocalName(i).length() == 0)) {
                        attr = doc.createAttribute(attQname);
                        attr.setNodeValue(atts.getValue(i));
                        if (prefix != null) {
                            attr.setPrefix(prefix);
                        }
                        ((Element)top).setAttributeNode(attr);
                    } else {
                        attr = doc.createAttributeNS(atts.getURI(i),
                                                     atts.getLocalName(i));
                        attr.setNodeValue(atts.getValue(i));
                        
                        if (prefix != null) {
                            attr.setPrefix(prefix);
                        }
                        ((Element)top).setAttributeNodeNS(attr);
                    }
                }
                previousTop.appendChild(top);
                depth++;
            } catch (DOMException e) {
                throw new SAXException(e.getMessage());
            }

        }

+++

Added support for [NodeCreateRule]

public class DigesterRuleParser extends RuleSetBase {

    public static javax.xml.parsers.DocumentBuilder documentBuilder;
    
    public static javax.xml.parsers.DocumentBuilder getDocumentBuilder() {
        return documentBuilder;
    }
    public static void setDocumentBuilder(
            javax.xml.parsers.DocumentBuilder documentBuilder) {
        DigesterRuleParser.documentBuilder = documentBuilder;
    }

    static {
        try {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        factory.setIgnoringComments(false);  
        factory.setCoalescing(false);
        factory.setIgnoringElementContentWhitespace(false);
        documentBuilder = factory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            System.err.println(e);
        }
    }

+++

    public void addRuleInstances(Digester digester) {

        digester.addFactoryCreate("*/node-create-rule", new NodeCreateRuleFactory());
        digester.addRule("*/node-create-rule", new PatternRule("pattern"));
        digester.addSetNext("*/node-create-rule", "add", ruleClassName);


    /**
     * Factory for creating a NodeCreateRule
     */
    protected class NodeCreateRuleFactory extends AbstractObjectCreationFactory {

        private boolean isNotEmpty(String str) {
            return (str != null && str.length() > 0);
        }

        public Object createObject(Attributes attributes) {
            String strDocumentBuilderFactoryClass = attributes
                    .getValue("documentbuilderfactory");
            String strDocumentBuilderClass = attributes
                    .getValue("documentbuilder");
            String strIsNsAware = attributes.getValue("namespaceaware");
            String strIsIgnoreComments = attributes.getValue("ignorecomments");
            String strIsFragment = attributes.getValue("fragment");
            boolean ignoreExceptions = "true".equalsIgnoreCase(attributes
                    .getValue("ignore-exceptions"));
            boolean isNewFactory = false;
//          Use custom DocumentBuilderFactory
            if (isNotEmpty(strDocumentBuilderFactoryClass)) {
                try {
                    DocumentBuilderFactory customDocumentBuilderFactory = (DocumentBuilderFactory)
Class
                            .forName(strDocumentBuilderFactoryClass)
                            .newInstance();
                    setDocumentBuilderFactory(customDocumentBuilderFactory);
                    isNewFactory = true;
                } catch (Exception e) {
                    System.err.println(e);
                }

            }
            // Use custom DocumentBuilder
            else if (isNotEmpty(strDocumentBuilderClass)) {
                try {
                    DocumentBuilder customDocumentBuilder = (DocumentBuilder) Class
                            .forName(strDocumentBuilderClass).newInstance();
                    setDocumentBuilder(customDocumentBuilder);
                } catch (Exception e) {
                    System.err.println(e);
                }
            }
            // customize DocumentBuilderFactory
            if (isNotEmpty(strIsNsAware) || isNotEmpty(strIsIgnoreComments)) {
                DocumentBuilderFactory factory = getDocumentBuilderFactory();
                if (isNotEmpty(strIsNsAware))
                    factory.setNamespaceAware(Boolean
                            .parseBoolean(strIsNsAware));
                if (isNotEmpty(strIsIgnoreComments))
                    factory.setNamespaceAware(Boolean
                            .parseBoolean(strIsIgnoreComments));

                setDocumentBuilderFactory(factory);
                isNewFactory = true;
            }
            // create new DocumentBuilder using new factory
            if (isNewFactory) {
                try {
                    setDocumentBuilder(getDocumentBuilderFactory()
                            .newDocumentBuilder());
                } catch (ParserConfigurationException e) {
                    System.err.println(e);
                }
            }
            // Create Rule for DOM Element or DocumentFragment
            if (strIsFragment == null || strIsFragment.length() == 0
                    || !Boolean.parseBoolean(strIsFragment)) {
                return new NodeCreateRule(getDocumentBuilder());
            } else {
                return new NodeCreateRule(Node.DOCUMENT_FRAGMENT_NODE,
                        getDocumentBuilder());
            }
        }
    }
+++
Test class

public class TestNodeCreateRule extends TestCase {
    
    public static String nodeToString(Node node) throws TransformerException {
        Source source = new DOMSource(node);
        StringWriter stringWriter = new StringWriter();
        Result result = new StreamResult(stringWriter);
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer();
        transformer.transform(source, result);
        return stringWriter.getBuffer().toString();
    }    
    
    public void testNodeCreateRule() throws Exception {
        
            URL rules = ClassLoader.getSystemResource
                ("org/apache/commons/digester/xmlrules/test-node-create-rules-w-rootobj.xml");
            
            String xml = "<?xml version='1.0' ?>"
                         + "<xcd:root xmlns:xcd='http://www.diku.dk'><foo attr='long'><xs:schema
targetNamespace='http://openuri.org/easypo' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:po='http://openuri.org/easypo'
elementFormDefault='qualified'>"
                         + "<xs:element name='purchase-order' xs:ID='A22'></xs:element></xs:schema></foo></xcd:root>";

            String xml2 = "<?xml version='1.0' ?>"
                + "<xcd:root xmlns:xcd='http://www.diku.dk'><xcd:dtd>this is a
dtd</xcd:dtd></xcd:root>";
            
            
            TestObject testObject = new TestObject();
            
            Digester d = DigesterLoader.createDigester(rules);
            d.setNamespaceAware(true);
            d.setRuleNamespaceURI("www.diku.dk");
            testObject = (TestObject) d.parse(new StringReader(xml));                    
   
            System.out.println("testObject:" + testObject);                              
                                 
            System.out.println("Node:" + nodeToString(testObject.getNode()));
            System.out.println("BinaryNode:" + nodeToString(testObject.getBinary()));
            System.out.println("Property:" + testObject.getProperty());
        }
}

+++

<!DOCTYPE digester-rules PUBLIC "-//Jakarta Apache //DTD digester-rules XML V1.0//EN" "http://jakarta.apache.org/commons/digester/dtds/digester-rules.dtd">

<digester-rules>
	<pattern value="root/foo">
		<object-create-rule classname="org.apache.commons.digester.xmlrules.TestObject"/>
		<node-create-rule fragment="true"/>
		<set-next-rule methodname="setNode"/>
	</pattern>
	<pattern value="root/dtd">
		<object-create-rule classname="org.apache.commons.digester.xmlrules.TestObject"/>
		<node-create-rule fragment="true"/>
		<set-next-rule methodname="setBinary"/>
	</pattern>
</digester-rules>

+++

public class TestObject {


    private Node binary = null;        

    private Node node = null;



    public Node getNode() {
        return node;
    }
    public void setNode(Node node) {
        this.node = node;
    }
    public Node getBinary() {
        return binary;
    }
    public void setBinary(Node binary) {
        this.binary = binary;
        setProperty(getBinary().getTextContent());
    }
}

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.779 / Virus Database: 526 - Release Date: 19-10-2004
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message