private void canonicalizeXPathNodeSet()

in src/main/java/org/apache/xml/security/c14n/implementations/CanonicalizerBase.java [321:456]


    private void canonicalizeXPathNodeSet(Node currentNode, Node endnode, OutputStream writer)
        throws CanonicalizationException, IOException {
        if (isVisibleInt(currentNode) == -1) {
            return;
        }
        boolean currentNodeIsVisible = false;
        NameSpaceSymbTable ns = new NameSpaceSymbTable();
        if (currentNode != null && Node.ELEMENT_NODE == currentNode.getNodeType()) {
            getParentNameSpaces((Element)currentNode, ns);
        }
        if (currentNode == null) {
            return;
        }
        Node sibling = null;
        Node parentNode = null;
        int documentLevel = NODE_BEFORE_DOCUMENT_ELEMENT;
        Map<String, byte[]> cache = new HashMap<>();
        do {    //NOPMD
            switch (currentNode.getNodeType()) {

            case Node.ENTITY_NODE :
            case Node.NOTATION_NODE :
            case Node.ATTRIBUTE_NODE :
                // illegal node type during traversal
                throw new CanonicalizationException("empty",
                                                    new Object[]{"illegal node type during traversal"});

            case Node.DOCUMENT_FRAGMENT_NODE :
            case Node.DOCUMENT_NODE :
                ns.outputNodePush();
                sibling = currentNode.getFirstChild();
                break;

            case Node.COMMENT_NODE :
                if (includeComments && isVisibleDO(currentNode, ns.getLevel()) == 1) {
                    outputCommentToWriter((Comment) currentNode, writer, documentLevel);
                }
                break;

            case Node.PROCESSING_INSTRUCTION_NODE :
                if (isVisible(currentNode)) {
                    outputPItoWriter((ProcessingInstruction) currentNode, writer, documentLevel);
                }
                break;

            case Node.TEXT_NODE :
            case Node.CDATA_SECTION_NODE :
                if (isVisible(currentNode)) {
                    outputTextToWriter(currentNode.getNodeValue(), writer);
                    for (Node nextSibling = currentNode.getNextSibling();
                        nextSibling != null && (nextSibling.getNodeType() == Node.TEXT_NODE
                            || nextSibling.getNodeType() == Node.CDATA_SECTION_NODE);
                        nextSibling = nextSibling.getNextSibling()) {
                        outputTextToWriter(nextSibling.getNodeValue(), writer);
                        currentNode = nextSibling;
                        sibling = currentNode.getNextSibling();
                    }
                }
                break;

            case Node.ELEMENT_NODE :
                documentLevel = NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT;
                Element currentElement = (Element) currentNode;
                //Add a level to the nssymbtable. So latter can be pop-back.
                String name = null;
                int i = isVisibleDO(currentNode, ns.getLevel());
                if (i == -1) {
                    sibling = currentNode.getNextSibling();
                    break;
                }
                currentNodeIsVisible = i == 1;
                if (currentNodeIsVisible) {
                    ns.outputNodePush();
                    writer.write('<');
                    name = currentElement.getTagName();
                    UtfHelpper.writeByte(name, writer, cache);
                } else {
                    ns.push();
                }

                outputAttributes(currentElement, ns, cache, writer);

                if (currentNodeIsVisible) {
                    writer.write('>');
                }
                sibling = currentNode.getFirstChild();

                if (sibling == null) {
                    if (currentNodeIsVisible) {
                        writer.write(END_TAG.clone());
                        UtfHelpper.writeByte(name, writer, cache);
                        writer.write('>');
                        //We finished with this level, pop to the previous definitions.
                        ns.outputNodePop();
                    } else {
                        ns.pop();
                    }
                    if (parentNode != null) {
                        sibling = currentNode.getNextSibling();
                    }
                } else {
                    parentNode = currentElement;
                }
                break;

            case Node.DOCUMENT_TYPE_NODE :
            default :
                break;
            }
            while (sibling == null && parentNode != null) {
                if (isVisible(parentNode)) {
                    writer.write(END_TAG.clone());
                    UtfHelpper.writeByte(((Element)parentNode).getTagName(), writer, cache);
                    writer.write('>');
                    //We finished with this level, pop to the previous definitions.
                    ns.outputNodePop();
                } else {
                    ns.pop();
                }
                if (parentNode == endnode) {
                    return;
                }
                sibling = parentNode.getNextSibling();
                parentNode = parentNode.getParentNode();
                if (parentNode == null || Node.ELEMENT_NODE != parentNode.getNodeType()) {
                    parentNode = null;
                    documentLevel = NODE_AFTER_DOCUMENT_ELEMENT;
                }
            }
            if (sibling == null) {
                return;
            }
            currentNode = sibling;
            sibling = currentNode.getNextSibling();
        } while(true);
    }