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

📄 element.java

📁 HTML解析器是一个Java库
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	 * Returns a list of the immediate children of this element in the document element hierarchy.
	 * <p>
	 * The objects in the list are all of type {@link Element}.
	 * <p>
	 * See the {@link Source#getChildElements()} method for more details.
	 *
	 * @return a list of the immediate children of this element in the document element hierarchy, guaranteed not <code>null</code>.
	 * @see #getParentElement()
	 */
	@Override public final List<Element> getChildElements() {
		return childElements!=null ? childElements : getChildElements(-1);
	}

	final List<Element> getChildElements(int depth) {
		if (depth!=-1) this.depth=depth;
		if (childElements==null) {
			if (!Config.IncludeServerTagsInElementHierarchy && end==startTag.end) {
				childElements=Collections.emptyList();
			} else {
				final int childDepth=(depth==-1 ? -1 : depth+1);
				childElements=new ArrayList<Element>();
				int pos=Config.IncludeServerTagsInElementHierarchy ? begin+1 : startTag.end;
				final int maxChildBegin=(Config.IncludeServerTagsInElementHierarchy || endTag==null) ? end : endTag.begin;
				while (true) {
					final StartTag childStartTag=source.getNextStartTag(pos);
					if (childStartTag==null || childStartTag.begin>=maxChildBegin) break;
					if (Config.IncludeServerTagsInElementHierarchy) {
						if (childStartTag.begin<startTag.end && !childStartTag.getTagType().isServerTag() && !startTag.getTagType().isServerTag()) {
							// A start tag is found within another start tag, but neither is a server tag.
							// This only legitimately happens in very rare cases like entity definitions in doctype.
							// We don't want to include the child elements in the hierarchy.
							pos=childStartTag.end;
							continue;
						}
					} else if (childStartTag.getTagType().isServerTag()) {
						pos=childStartTag.end;
						continue;
					}
					final Element childElement=childStartTag.getElement();
					if (childElement.end>end) {
						if (source.logger.isInfoEnabled()) source.logger.info("Child "+childElement.getDebugInfo()+" extends beyond end of parent "+getDebugInfo());
						if (!INCLUDE_INCORRECTLY_NESTED_CHILDREN_IN_HIERARCHY) {
							pos=childElement.end; 
							continue; 
						}
					}
					childElement.getChildElements(childDepth);
					if (childElement.parentElement==Element.NOT_CACHED) { // make sure element was not added as a child of a descendent element (can happen with overlapping elements)
						childElement.parentElement=this;
						childElements.add(childElement);
					}
					pos=childElement.end;
				}
			}
		}
		return childElements;
	}

	/**
	 * Returns the nesting depth of this element in the document element hierarchy.
	 * <p>
	 * The {@link Source#fullSequentialParse()} method must be called (either explicitly or implicitly) after construction of the <code>Source</code> object if this method is to be used.
	 * An <code>IllegalStateException</code> is thrown if a full sequential parse has not been performed or if it was performed after this element was found.
	 * <p>
	 * A <a href="Source.html#TopLevelElement">top-level element</a> has a nesting depth of <code>0</code>.
	 * <p>
	 * An element formed from a {@linkplain TagType#isServerTag() server tag} always have a nesting depth of <code>0</code>,
	 * regardless of whether it is nested inside a normal element.
	 * <p>
	 * See the {@link Source#getChildElements()} method for more details.
	 *
	 * @return the nesting depth of this element in the document element hierarchy.
	 * @throws IllegalStateException if a {@linkplain Source#fullSequentialParse() full sequential parse} has not been performed or if it was performed after this element was found.
	 * @see #getParentElement()
	 */
	public int getDepth() {
		if (depth==-1) {
			getParentElement();
			if (depth==-1) depth=0;
		}
		return depth;
	}

	/**
	 * Returns the segment representing the <a target="_blank" href="http://www.w3.org/TR/REC-xml#dt-content">content</a> of the element.
	 * <p>
	 * This segment spans between the end of the start tag and the start of the end tag.
	 * If the end tag is not present, the content reaches to the end of the element.
	 * <p>
	 * A zero-length segment is returned if the element is {@linkplain #isEmpty() empty},
	 *
	 * @return the segment representing the content of the element, guaranteed not <code>null</code>.
	 */
	public Segment getContent() {
		if (content==null) content=new Segment(source,startTag.end,getContentEnd());
		return content;
	}

	/**
	 * Returns the start tag of the element.
	 * @return the start tag of the element.
	 */
	public StartTag getStartTag() {
		return startTag;
	}

	/**
	 * Returns the end tag of the element.
	 * <p>
	 * If the element has no end tag this method returns <code>null</code>.
	 *
	 * @return the end tag of the element, or <code>null</code> if the element has no end tag.
	 */
	public EndTag getEndTag() {
		return endTag;
	}

	/**
	 * Returns the {@linkplain StartTag#getName() name} of the {@linkplain #getStartTag() start tag} of this element, always in lower case.
	 * <p>
	 * This is equivalent to {@link #getStartTag()}<code>.</code>{@link StartTag#getName() getName()}.
	 * <p>
	 * See the {@link Tag#getName()} method for more information.
	 *
	 * @return the name of the {@linkplain #getStartTag() start tag} of this element, always in lower case.
	 */
	public String getName() {
		return startTag.getName();
	}

	/**
	 * Indicates whether this element has zero-length {@linkplain #getContent() content}.
	 * <p>
	 * This is equivalent to {@link #getContent()}<code>.</code>{@link Segment#length() length()}<code>==0</code>.
	 * <p>
	 * Note that this is a broader definition than that of both the
	 * <a target="_blank" href="http://www.w3.org/TR/html401/intro/sgmltut.html#didx-element-4">HTML definition of an empty element</a>,
	 * which is only those elements whose end tag is {@linkplain HTMLElements#getEndTagForbiddenElementNames() forbidden}, and the
	 * <a target="_blank" href="http://www.w3.org/TR/REC-xml#dt-empty">XML definition of an empty element</a>,
	 * which is "either a start-tag immediately followed by an end-tag, or an {@linkplain #isEmptyElementTag() empty-element tag}".
	 * The other possibility covered by this property is the case of an <a href="HTMLElements.html#HTMLElement">HTML element</a> with an
	 * {@linkplain HTMLElements#getEndTagOptionalElementNames() optional} end tag that is immediately followed by another tag that implicitly 
	 * terminates the element.
	 *
	 * @return <code>true</code> if this element has zero-length {@linkplain #getContent() content}, otherwise <code>false</code>.
	 * @see #isEmptyElementTag()
	 */
	public boolean isEmpty() {
		return startTag.end==getContentEnd();
	}

	/**
	 * Indicates whether this element is an <a target="_blank" href="http://www.w3.org/TR/REC-xml#dt-eetag">empty-element tag</a>.
	 * <p>
	 * This is equivalent to {@link #getStartTag()}<code>.</code>{@link StartTag#isEmptyElementTag() isEmptyElementTag()}.
	 * <p>
	 * Prior to Version 2.6, this method was equivalent to:<br />
	 * {@link #isEmpty()}<code> && </code>{@link #getStartTag()}<code>.</code>{@link StartTag#isSyntacticalEmptyElementTag() isSyntacticalEmptyElementTag()}.<br />
	 * It was changed to make it identical with the new behaviour of the {@link StartTag#isEmptyElementTag()}.
	 * In practice there are very few circumstances where the result is different to the old implementation of this method.
	 *
	 * @return <code>true</code> if this element is an <a target="_blank" href="http://www.w3.org/TR/REC-xml#dt-eetag">empty-element tag</a>, otherwise <code>false</code>.
	 */
	public boolean isEmptyElementTag() {
		return startTag.isEmptyElementTag();
	}

	/**
	 * Returns the attributes specified in this element's start tag.
	 * <p>
	 * This is equivalent to {@link #getStartTag()}<code>.</code>{@link StartTag#getAttributes() getAttributes()}.
	 *
	 * @return the attributes specified in this element's start tag.
	 * @see StartTag#getAttributes()
	 */
	public Attributes getAttributes() {
		return getStartTag().getAttributes();
	}

	/**
	 * Returns the {@linkplain CharacterReference#decode(CharSequence) decoded} value of the attribute with the specified name (case insensitive).
	 * <p>
	 * Returns <code>null</code> if the {@linkplain #getStartTag() start tag of this element} does not
	 * {@linkplain StartTagType#hasAttributes() have attributes},
	 * no attribute with the specified name exists or the attribute {@linkplain Attribute#hasValue() has no value}.
	 * <p>
	 * This is equivalent to {@link #getStartTag()}<code>.</code>{@link StartTag#getAttributeValue(String) getAttributeValue(attributeName)}.
	 *
	 * @param attributeName  the name of the attribute to get.
	 * @return the {@linkplain CharacterReference#decode(CharSequence) decoded} value of the attribute with the specified name, or <code>null</code> if the attribute does not exist or {@linkplain Attribute#hasValue() has no value}.
	 */
	public String getAttributeValue(final String attributeName) {
		return getStartTag().getAttributeValue(attributeName);
	}

	/**
	 * Returns the {@link FormControl} defined by this element.
	 * @return the {@link FormControl} defined by this element, or <code>null</code> if it is not a <a target="_blank" href="http://www.w3.org/TR/html401/interact/forms.html#form-controls">control</a>.
	 */
	public FormControl getFormControl() {
		return FormControl.construct(this);
	}

	public String getDebugInfo() {
		if (this==NOT_CACHED) return "NOT_CACHED";
		final StringBuilder sb=new StringBuilder();
		sb.append("Element ");
		startTag.appendDebugTag(sb);
		if (!isEmpty()) sb.append('-');
		if (endTag!=null) sb.append(endTag);
		sb.append(' ');
		startTag.appendDebugTagType(sb);
		sb.append(super.getDebugInfo());
		return sb.toString();
	}

	int getContentEnd() {
		return endTag!=null ? endTag.begin : end;
	}
	
	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.
	 */
	@Deprecated
	public static final String A=HTMLElementName.A;

	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.
	 */
	@Deprecated
	public static final String ABBR=HTMLElementName.ABBR;

	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.
	 */
	@Deprecated
	public static final String ACRONYM=HTMLElementName.ACRONYM;

	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.
	 */
	@Deprecated
	public static final String ADDRESS=HTMLElementName.ADDRESS;

	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.
	 */
	@Deprecated
	public static final String APPLET=HTMLElementName.APPLET;

	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.
	 */
	@Deprecated
	public static final String AREA=HTMLElementName.AREA;

	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.
	 */
	@Deprecated
	public static final String B=HTMLElementName.B;

	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.
	 */
	@Deprecated
	public static final String BASE=HTMLElementName.BASE;

	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.
	 */
	@Deprecated
	public static final String BASEFONT=HTMLElementName.BASEFONT;

	/**
	 * Use of this inherited static field has been deprecated as of version 3.0.
	 * @deprecated  Use the static field directly from the HTMLElementName class instead.

⌨️ 快捷键说明

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