jodd-lagarto/src/main/java/jodd/lagarto/dom/LagartoDOMBuilderTagVisitor.java
protected void fixUnclosedTagsUpToMatchingParent(final Tag tag, final Node matchingParent) {
		if (domBuilder.config.isUnclosedTagAsOrphanCheck()) {
			Node thisNode = parentNode;

			if (!CharSequenceUtil.equalsIgnoreCase(tag.getName(), "table")) {

				// check if there is table or list between this node
				// and matching parent
				while (thisNode != matchingParent) {
					String thisNodeName = thisNode.getNodeName().toLowerCase();

					if (thisNodeName.equals("table") || thisNodeName.equals("ul") || thisNodeName.equals("ol")) {

						String positionString = tag.getPosition();
						if (positionString == null) {
							positionString = StringPool.EMPTY;
						}

						error("Orphan closed tag ignored: </" + tag.getName() + "> " + positionString);
						return;
					}
					thisNode = thisNode.getParentNode();
				}
			}
		}

		while (true) {
			if (parentNode == matchingParent) {
				parentNode = parentNode.getParentNode();
				break;
			}

			Node parentParentNode = parentNode.getParentNode();

			if (domBuilder.config.isImpliedEndTags()) {
				if (implRules.implicitlyCloseParentTagOnNewTag(
						parentParentNode.getNodeName(), parentNode.getNodeName())) {
					// break the tree: detach this node and append it after parent

					parentNode.detachFromParent();

					parentParentNode.getParentNode().addChild(parentNode);
				}
			}

			// debug message

			error("Unclosed tag closed: <" + parentNode.getNodeName() + ">");

			// continue looping
			parentNode = parentParentNode;
		}
	}
protected void fixUnclosedTagsUpToMatchingParent(final Tag tag, final Node matchingParent) {
		if (domBuilder.config.isUnclosedTagAsOrphanCheck()) {
			Node thisNode = parentNode;

			if (!CharSequenceUtil.equalsIgnoreCase(tag.getName(), "table")) {

				// check if there is table or list between this node
				// and matching parent
				while (thisNode != matchingParent) {
					String thisNodeName = thisNode.getNodeName().toLowerCase();

					if (thisNodeName.equals("table") || thisNodeName.equals("ul") || thisNodeName.equals("ol")) {

						String positionString = tag.getPosition();
						if (positionString == null) {
							positionString = StringPool.EMPTY;
						}

						error("Orphan closed tag ignored: </" + tag.getName() + "> " + positionString);
						return;
					}
					thisNode = thisNode.getParentNode();
				}
			}
		}

		while (true) {
			if (parentNode == matchingParent) {
				parentNode = parentNode.getParentNode();
				break;
			}

			Node parentParentNode = parentNode.getParentNode();

			if (domBuilder.config.isImpliedEndTags()) {
				if (implRules.implicitlyCloseParentTagOnNewTag(
						parentParentNode.getNodeName(), parentNode.getNodeName())) {
					// break the tree: detach this node and append it after parent

					parentNode.detachFromParent();

					parentParentNode.getParentNode().addChild(parentNode);
				}
			}

			// debug message

			error("Unclosed tag closed: <" + parentNode.getNodeName() + ">");

			// continue looping
			parentNode = parentParentNode;
		}
	}
protected void fixUnclosedTagsUpToMatchingParent ( final Tag tag , final Node matchingParent ) { if ( domBuilder . config . isUnclosedTagAsOrphanCheck ( ) ) { Node thisNode = parentNode ; if ( ! CharSequenceUtil . equalsIgnoreCase ( tag . getName ( ) , "table" ) ) { // check if there is table or list between this node // and matching parent while ( thisNode != matchingParent ) { String thisNodeName = thisNode . getNodeName ( ) . toLowerCase ( ) ; if ( thisNodeName . equals ( "table" ) || thisNodeName . equals ( "ul" ) || thisNodeName . equals ( "ol" ) ) { String positionString = tag . getPosition ( ) ; if ( positionString == null ) { positionString = StringPool . EMPTY ; } error ( "Orphan closed tag ignored: </" + tag . getName ( ) + "> " + positionString ) ; return ; } thisNode = thisNode . getParentNode ( ) ; } } } while ( true ) { if ( parentNode == matchingParent ) { parentNode = parentNode . getParentNode ( ) ; break ; } Node parentParentNode = parentNode . getParentNode ( ) ; if ( domBuilder . config . isImpliedEndTags ( ) ) { if ( implRules . implicitlyCloseParentTagOnNewTag ( parentParentNode . getNodeName ( ) , parentNode . getNodeName ( ) ) ) { // break the tree: detach this node and append it after parent parentNode . detachFromParent ( ) ; parentParentNode . getParentNode ( ) . addChild ( parentNode ) ; } } // debug message error ( "Unclosed tag closed: <" + parentNode . getNodeName ( ) + ">" ) ; // continue looping parentNode = parentParentNode ; } }
Fixes all unclosed tags up to matching parent. Missing end tags will be added
just before parent tag is closed, making the whole inner content as its tag body.
<p>
Tags that can be closed implicitly are checked and closed.
<p>
There is optional check for detecting orphan tags inside the
table or lists. If set, tags can be closed beyond the border of the
table and the list and it is reported as orphan tag.
<p>
This is just a generic solutions, closest to the rules.
Fixes all unclosed tags up to matching parent . Missing end tags will be added just before parent tag is closed making the whole inner content as its tag body . <p > Tags that can be closed implicitly are checked and closed . <p > There is optional check for detecting orphan tags inside the table or lists . If set tags can be closed beyond the border of the table and the list and it is reported as orphan tag . <p > This is just a generic solutions closest to the rules .