⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmsxmlutils.java

📁 cms是开源的框架
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding(encoding);
            format.setSuppressDeclaration(true);

            XMLWriter writer = new XMLWriter(out, format);
            writer.setEscapeText(false);

            writer.write(node);
            writer.close();
        } catch (Exception e) {
            throw new CmsXmlException(Messages.get().container(Messages.ERR_MARSHALLING_XML_DOC_0), e);
        }
        return new String(out.toByteArray());
    }

    /**
     * Removes the first Xpath element from the path.<p>
     * 
     * If the provided path does not contain a "/" character, 
     * it is returned unchanged.<p>
     * 
     * <p>Examples:<br> 
     * <code>title</code> is left untouched<br>
     * <code>title[1]</code> is left untouched<br>
     * <code>title/subtitle</code> becomes <code>subtitle</code><br>
     * <code>title[1]/subtitle[1]</code> becomes <code>subtitle[1]</code><p>
     * 
     * @param path the Xpath to remove the first element from
     * 
     * @return the path with the first element removed
     */
    public static String removeFirstXpathElement(String path) {

        int pos = path.indexOf('/');
        if (pos < 0) {
            return path;
        }

        return path.substring(pos + 1);
    }

    /**
     * Removes the last Xpath element from the path.<p>
     * 
     * If the provided path does not contain a "/" character, 
     * it is returned unchanged.<p>
     * 
     * <p>Examples:<br> 
     * <code>title</code> is left untouched<br>
     * <code>title[1]</code> is left untouched<br>
     * <code>title/subtitle</code> becomes <code>title</code><br>
     * <code>title[1]/subtitle[1]</code> becomes <code>title[1]</code><p>
     * 
     * @param path the Xpath to remove the last element from
     * 
     * @return the path with the last element removed
     */
    public static String removeLastXpathElement(String path) {

        int pos = path.lastIndexOf('/');
        if (pos < 0) {
            return path;
        }

        return path.substring(0, pos);
    }

    /**
     * Removes the last complex Xpath element from the path.<p>
     * 
     * The same as {@link #removeLastXpathElement(String)} both it works with more complex xpaths.
     * 
     * <p>Example:<br> 
     * <code>system/backup[@date='23/10/2003']/resource[path='/a/b/c']</code> becomes <code>system/backup[@date='23/10/2003']</code><p>
     * 
     * @param path the Xpath to remove the last element from
     * 
     * @return the path with the last element removed
     */
    public static String removeLastComplexXpathElement(String path) {

        int pos = path.lastIndexOf('/');
        if (pos < 0) {
            return path;
        }
        // count ' chars
        int p = pos;
        int count = -1;
        while (p > 0) {
            count++;
            p = path.indexOf("\'", p + 1);
        }
        String parentPath = path.substring(0, pos);
        if (count % 2 == 0) {
            // if substring is complete 
            return parentPath;
        }
        // if not complete
        p = parentPath.lastIndexOf("'");
        if (p >= 0) {
            // complete it if possible
            return removeLastComplexXpathElement(parentPath.substring(0, p));
        }
        return parentPath;
    }

    /**
     * Removes all Xpath index information from the given input path.<p>
     * 
     * Examples:<br> 
     * <code>title</code> is left untouched<br>
     * <code>title[1]</code> becomes <code>title</code><br>
     * <code>title/subtitle</code> is left untouched<br>
     * <code>title/subtitle[1]</code> becomes <code>title/subtitle</code><p>
     * 
     * @param path the path to remove the Xpath index information from
     * 
     * @return the simplified Xpath for the given name
     */
    public static String removeXpath(String path) {

        if (path.indexOf('/') > -1) {
            // this is a complex path over more then 1 node
            StringBuffer result = new StringBuffer(path.length() + 32);

            // split the path into subelements
            List elements = CmsStringUtil.splitAsList(path, '/');
            int end = elements.size() - 1;
            for (int i = 0; i <= end; i++) {
                // append [i] to path element if required 
                result.append(removeXpathIndex((String)elements.get(i)));
                if (i < end) {
                    // append path delimiter if not final path element
                    result.append('/');
                }
            }
            return result.toString();
        }

        // this path has only 1 node, remove last index if required
        return removeXpathIndex(path);
    }

    /**
     * Removes the last Xpath index from the given path.<p>
     * 
     * Examples:<br> 
     * <code>title</code> is left untouched<br>
     * <code>title[1]</code> becomes <code>title</code><br>
     * <code>title/subtitle</code> is left untouched<br>
     * <code>title[1]/subtitle[1]</code> becomes <code>title[1]/subtitle</code><p>
     * 
     * @param path the path to remove the Xpath index from
     * 
     * @return the path with the last Xpath index removed
     */
    public static String removeXpathIndex(String path) {

        int pos1 = path.lastIndexOf('/');
        int pos2 = path.lastIndexOf('[');
        if ((pos2 < 0) || (pos1 > pos2)) {
            return path;
        }

        return path.substring(0, pos2);
    }

    /**
     * Simplifies an Xpath by removing a leading and a trailing slash from the given path.<p> 
     * 
     * Examples:<br> 
     * <code>title/</code> becomes <code>title</code><br>
     * <code>/title[1]/</code> becomes <code>title[1]</code><br>
     * <code>/title/subtitle/</code> becomes <code>title/subtitle</code><br>
     * <code>/title/subtitle[1]/</code> becomes <code>title/subtitle[1]</code><p>
     * 
     * @param path the path to process
     * @return the input with a leading and a trailing slash removed
     */
    public static String simplifyXpath(String path) {

        StringBuffer result = new StringBuffer(path);
        if (result.charAt(0) == '/') {
            result.deleteCharAt(0);
        }
        int pos = result.length() - 1;
        if (result.charAt(pos) == '/') {
            result.deleteCharAt(pos);
        }
        return result.toString();
    }

    /**
     * Helper to unmarshal (read) xml contents from a byte array into a document.<p>
     * 
     * Using this method ensures that the OpenCms XML entitiy resolver is used.<p>
     * 
     * @param xmlData the XML data in a byte array
     * @param resolver the XML entitiy resolver to use
     * @return the base object initialized with the unmarshalled XML document
     * @throws CmsXmlException if something goes wrong
     * @see CmsXmlUtils#unmarshalHelper(InputSource, EntityResolver)
     */
    public static Document unmarshalHelper(byte[] xmlData, EntityResolver resolver) throws CmsXmlException {

        return CmsXmlUtils.unmarshalHelper(new InputSource(new ByteArrayInputStream(xmlData)), resolver);
    }

    /**
     * Helper to unmarshal (read) xml contents from an input source into a document.<p>
     * 
     * Using this method ensures that the OpenCms XML entitiy resolver is used.<p>
     * 
     * Important: The encoding provided will NOT be used uring unmarshalling,
     * the XML parser will do this on the base of the information in the source String.
     * The encoding is used for initializing the created instance of the document,
     * which means it will be used when marshalling the document again later.<p>
     *  
     * @param source the XML input source to use
     * @param resolver the XML entitiy resolver to use
     * @return the unmarshalled XML document
     * @throws CmsXmlException if something goes wrong
     */
    public static Document unmarshalHelper(InputSource source, EntityResolver resolver) throws CmsXmlException {

        try {
            SAXReader reader = new SAXReader();
            if (resolver != null) {
                reader.setEntityResolver(resolver);
            }
            reader.setMergeAdjacentText(true);
            reader.setStripWhitespaceText(true);
            return reader.read(source);
        } catch (DocumentException e) {
            throw new CmsXmlException(Messages.get().container(Messages.ERR_UNMARSHALLING_XML_DOC_0), e);
        }
    }

    /**
     * Helper to unmarshal (read) xml contents from a String into a document.<p>
     * 
     * Using this method ensures that the OpenCms XML entitiy resolver is used.<p>
     * 
     * @param xmlData the xml data in a String 
     * @param resolver the XML entitiy resolver to use
     * @return the base object initialized with the unmarshalled XML document
     * @throws CmsXmlException if something goes wrong
     * @see CmsXmlUtils#unmarshalHelper(InputSource, EntityResolver)
     */
    public static Document unmarshalHelper(String xmlData, EntityResolver resolver) throws CmsXmlException {

        return CmsXmlUtils.unmarshalHelper(new InputSource(new StringReader(xmlData)), resolver);
    }

    /**
     * Validates the structure of a XML document contained in a byte array 
     * with the DTD or XML schema used by the document.<p>
     * 
     * @param xmlData a byte array containing a XML document that should be validated
     * @param resolver the XML entitiy resolver to use
     * 
     * @throws CmsXmlException if the validation fails
     */
    public static void validateXmlStructure(byte[] xmlData, EntityResolver resolver) throws CmsXmlException {

        XMLReader reader;
        try {
            reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
        } catch (SAXException e) {
            // xerces parser not available - no schema validation possible
            if (LOG.isWarnEnabled()) {
                LOG.warn(Messages.get().getBundle().key(Messages.LOG_VALIDATION_INIT_XERXES_SAX_READER_FAILED_0), e);
            }
            // no validation of the content is possible
            return;
        }
        // turn on validation
        try {
            reader.setFeature("http://xml.org/sax/features/validation", true);
            // turn on schema validation
            reader.setFeature("http://apache.org/xml/features/validation/schema", true);
            // configure namespace support
            reader.setFeature("http://xml.org/sax/features/namespaces", true);
            reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
        } catch (SAXNotRecognizedException e) {
            // should not happen as Xerces 2 support this feature
            if (LOG.isWarnEnabled()) {
                LOG.warn(Messages.get().getBundle().key(Messages.LOG_SAX_READER_FEATURE_NOT_RECOGNIZED_0), e);
            }
            // no validation of the content is possible
            return;
        } catch (SAXNotSupportedException e) {
            // should not happen as Xerces 2 support this feature
            if (LOG.isWarnEnabled()) {
                LOG.warn(Messages.get().getBundle().key(Messages.LOG_SAX_READER_FEATURE_NOT_SUPPORTED_0), e);
            }
            // no validation of the content is possible
            return;
        }

        // add an error handler which turns any errors into XML
        CmsXmlValidationErrorHandler errorHandler = new CmsXmlValidationErrorHandler();
        reader.setErrorHandler(errorHandler);

        if (resolver != null) {
            // set the resolver for the "opencms://" URIs
            reader.setEntityResolver(resolver);
        }

        try {
            reader.parse(new InputSource(new ByteArrayInputStream(xmlData)));
        } catch (IOException e) {
            // should not happen since we read form a byte array
            if (LOG.isErrorEnabled()) {
                LOG.error(Messages.get().getBundle().key(Messages.LOG_READ_XML_FROM_BYTE_ARR_FAILED_0), e);
            }
            return;
        } catch (SAXException e) {
            // should not happen since all errors are handled in the XML error handler
            if (LOG.isErrorEnabled()) {
                LOG.error(Messages.get().getBundle().key(Messages.LOG_PARSE_SAX_EXC_0), e);
            }
            return;
        }

        if (errorHandler.getErrors().elements().size() > 0) {
            // there was at last one validation error, so throw an exception
            StringWriter out = new StringWriter(256);
            OutputFormat format = OutputFormat.createPrettyPrint();
            XMLWriter writer = new XMLWriter(out, format);
            try {
                writer.write(errorHandler.getErrors());
                writer.write(errorHandler.getWarnings());
                writer.close();
            } catch (IOException e) {
                // should not happen since we write to a StringWriter
                if (LOG.isErrorEnabled()) {
                    LOG.error(Messages.get().getBundle().key(Messages.LOG_STRINGWRITER_IO_EXC_0), e);
                }
            }
            // generate String from XML for display of document in error message
            throw new CmsXmlException(Messages.get().container(Messages.ERR_XML_VALIDATION_1, out.toString()));
        }
    }

    /**
     * Validates the structure of a XML document with the DTD or XML schema used 
     * by the document.<p>
     * 
     * @param document a XML document that should be validated
     * @param encoding the encoding to use when marshalling the XML document (required)
     * @param resolver the XML entitiy resolver to use
     * 
     * @throws CmsXmlException if the validation fails
     */
    public static void validateXmlStructure(Document document, String encoding, EntityResolver resolver)
    throws CmsXmlException {

        // generate bytes from document
        byte[] xmlData = ((ByteArrayOutputStream)marshal(document, new ByteArrayOutputStream(512), encoding)).toByteArray();
        validateXmlStructure(xmlData, resolver);
    }
}

⌨️ 快捷键说明

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