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

📄 starttag.java

📁 HTML解析器是一个Java库
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	 * <code>NullPointerException</code>.
	 *
	 * @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 attributes==null ? null : attributes.getValue(attributeName);
	}

	/**
	 * Parses the attributes specified in this start tag, regardless of the type of start tag.
	 * This method is only required in the unusual situation where attributes exist in a start tag whose 
	 * {@linkplain #getStartTagType() type} doesn't {@linkplain StartTagType#hasAttributes() have attributes}.
	 * <p>
	 * This method returns the cached attributes from the {@link StartTag#getAttributes()} method
	 * if its value is not <code>null</code>, otherwise the source is physically parsed with each call to this method.
	 * <p>
	 * This is equivalent to {@link #parseAttributes(int) parseAttributes}<code>(</code>{@link Attributes#getDefaultMaxErrorCount()}<code>)}</code>.
	 *
	 * @return the attributes specified in this start tag, or <code>null</code> if too many errors occur while parsing.
	 * @see #getAttributes()
	 * @see Source#parseAttributes(int pos, int maxEnd)
	 */
	public Attributes parseAttributes() {
		return parseAttributes(Attributes.getDefaultMaxErrorCount());
	}

	/**
	 * Parses the attributes specified in this start tag, regardless of the type of start tag.
	 * This method is only required in the unusual situation where attributes exist in a start tag whose 
	 * {@linkplain #getStartTagType() type} doesn't {@linkplain StartTagType#hasAttributes() have attributes}.
	 * <p>
	 * See the documentation of the {@link #parseAttributes()} method for more information.
	 *
	 * @param maxErrorCount  the maximum number of minor errors allowed while parsing
	 * @return the attributes specified in this start tag, or <code>null</code> if too many errors occur while parsing.
	 * @see #getAttributes()
	 */
	public Attributes parseAttributes(final int maxErrorCount) {
		if (attributes!=null) return attributes;
		final int maxEnd=end-startTagType.getClosingDelimiter().length();
		int attributesBegin=begin+1+name.length();
		// skip any non-name characters directly after the name (which are quite common)
		while (!isXMLNameStartChar(source.charAt(attributesBegin))) {
			attributesBegin++;
			if (attributesBegin==maxEnd) return null;
		}
		return Attributes.construct(source,begin,attributesBegin,maxEnd,startTagType,name,maxErrorCount);
	}

	/**
	 * Returns the segment between the end of the tag's {@linkplain #getName() name} and the start of its <a href="#EndDelimiter">end delimiter</a>.
	 * <p>
	 * This method is normally only of use for start tags whose content is something other than {@linkplain #getAttributes() attributes}.
	 * <p>
	 * A new {@link Segment} object is created with each call to this method.
	 *
	 * @return the segment between the end of the tag's {@linkplain #getName() name} and the start of the <a href="#EndDelimiter">end delimiter</a>.
	 */
	public Segment getTagContent() {
		return new Segment(source,begin+1+name.length(),end-startTagType.getClosingDelimiter().length());
	}

	/**
	 * Returns the {@link FormControl} defined by this start tag.
	 * <p>
	 * This is equivalent to {@link #getElement()}<code>.</code>{@link Element#getFormControl() getFormControl()}.
	 *
	 * @return the {@link FormControl} defined by this start tag, 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 getElement().getFormControl();
	}

	/**
	 * Indicates whether a matching end tag is forbidden.
	 * <p>
	 * This property returns <code>true</code> if one of the following conditions is met:
	 * <ul>
	 *  <li>The {@linkplain #getStartTagType() type} of this start tag does not specify a
	 *   {@linkplain StartTagType#getCorrespondingEndTagType() corresponding end tag type}.
	 *  <li>The {@linkplain #getName() name} of this start tag indicates it is the start of an
	 *   <a href="Element.html#HTML">HTML element</a> whose {@linkplain HTMLElements#getEndTagForbiddenElementNames() end tag is forbidden}.
	 *  <li>This start tag is {@linkplain #isSyntacticalEmptyElementTag() syntactically an empty-element tag} and its
	 *   {@linkplain #getName() name} indicates it is the start of a <a href="HTMLElements.html#NonHTMLElement">non-HTML element</a>.
	 * </ul>
	 * <p>
	 * If this property returns <code>true</code> then this start tag's {@linkplain #getElement() element} will always be a
	 * <a href="Element.html#SingleTag">single tag element</a>.
	 *
	 * @return  <code>true</code> if a matching end tag is forbidden, otherwise <code>false</code>.
	 */
	public boolean isEndTagForbidden() {
		if (getStartTagType()!=StartTagType.NORMAL)
			return getStartTagType().getCorrespondingEndTagType()==null;
		if (HTMLElements.getEndTagForbiddenElementNames().contains(name)) return true;
		if (HTMLElements.getElementNames().contains(name)) return false;
		return isSyntacticalEmptyElementTag();
	}

	/**
	 * Indicates whether a matching end tag is required.
	 * <p>
	 * This property returns <code>true</code> if one of the following conditions is met:
	 * <ul>
	 *  <li>The {@linkplain #getStartTagType() type} of this start tag is NOT {@link StartTagType#NORMAL}, but specifies a
	 *   {@linkplain StartTagType#getCorrespondingEndTagType() corresponding end tag type}.
	 *  <li>The {@linkplain #getName() name} of this start tag indicates it is the start of an
	 *   <a href="Element.html#HTML">HTML element</a> whose {@linkplain HTMLElements#getEndTagRequiredElementNames() end tag is required}.
	 *  <li>This start tag is NOT {@linkplain #isSyntacticalEmptyElementTag() syntactically an empty-element tag} and its
	 *   {@linkplain #getName() name} indicates it is the start of a <a href="HTMLElements.html#NonHTMLElement">non-HTML element</a>.
	 * </ul>
	 *
	 * @return  <code>true</code> if a matching end tag is required, otherwise <code>false</code>.
	 */
	public boolean isEndTagRequired() {
		if (getStartTagType()!=StartTagType.NORMAL)
			return getStartTagType().getCorrespondingEndTagType()!=null;
		if (HTMLElements.getEndTagRequiredElementNames().contains(name)) return true;
		if (HTMLElements.getElementNames().contains(name)) return false;
		return !isSyntacticalEmptyElementTag();
	}

	// Documentation inherited from Tag
	public boolean isUnregistered() {
		return startTagType==StartTagType.UNREGISTERED;
	}

	/**
	 * Returns an XML representation of this start tag.
	 * <p>
	 * This is equivalent to {@link #tidy(boolean) tidy(false)}, thereby keeping the {@linkplain #getName() name} of the tag in its original case.
	 * <p>
	 * See the documentation of the {@link #tidy(boolean toXHTML)} method for more details.
	 *
	 * @return an XML representation of this start tag, or the {@linkplain Segment#toString() source text} if it is of a {@linkplain #getStartTagType() type} that does not {@linkplain StartTagType#hasAttributes() have attributes}.
	 */
	public String tidy() {
		return tidy(false);
	}

	/**
	 * Returns an XML or XHTML representation of this start tag.
	 * <p>
	 * The tidying of the tag is carried out as follows:
	 * <ul>
	 *  <li>if this start tag is of a {@linkplain #getStartTagType() type} that does not {@linkplain StartTagType#hasAttributes() have attributes},
	 *   then the original {@linkplain Segment#toString() source text} of the enture tag is returned.
	 *  <li>if this start tag contain any {@linkplain TagType#isServerTag() server tags} outside of an attribute value,
	 *   then the original {@linkplain Segment#toString() source text} of the entire tag is returned.
	 *  <li>name converted to lower case if the <code>toXHTML</code> argument is <code>true</code> and this is a {@linkplain StartTagType#NORMAL normal} start tag
	 *  <li>attributes separated by a single space
	 *  <li>attribute names in original case
	 *  <li>attribute values are enclosed in double quotes and {@linkplain CharacterReference#reencode(CharSequence) re-encoded}
	 *  <li>if this start tag forms an <a href="Element.html#HTML">HTML element</a> that has no {@linkplain Element#getEndTag() end tag},
	 *   a slash is inserted before the closing angle bracket, separated from the {@linkplain #getName() name} or last attribute by a single space.
	 *  <li>if an attribute value contains a {@linkplain TagType#isServerTag() server tag} it is inserted verbatim instead of being
	 *   {@linkplain CharacterReference#encode(CharSequence) encoded}.
	 * </ul>
	 * <p>
	 * The <code>toXHTML</code> parameter determines only whether the name is converted to lower case for {@linkplain StartTagType#NORMAL normal} tags.
	 * In all other respects the generated tag is already valid XHTML.
	 * <p>
	 * <dl>
	 *  <dt>Example:</dt>
	 *  <dd>
	 *   <p>
	 *   The following source text:
	 *   <blockquote class="code">
	 *    <code>&lt;INPUT name=Company value='G&amp;uuml;nter O&amp#39;Reilly &amp;amp Associ&eacute;s'&gt;</code>
	 *   </blockquote>
	 *   produces the following regenerated HTML:
	 *   <blockquote class="code">
	 *    <code>&lt;input name="Company" value="G&amp;uuml;nter O'Reilly &amp;amp; Associ&amp;eacute;s" /&gt;</code>
	 *   </blockquote>
	 *  </dd>
	 * </dl>
	 *
	 * @param toXHTML  specifies whether the output is XHTML.
	 * @return an XML or XHTML representation of this start tag, or the {@linkplain Segment#toString() source text} if it is of a {@linkplain #getStartTagType() type} that does not {@linkplain StartTagType#hasAttributes() have attributes}.
	 */
	public String tidy(boolean toXHTML) {
		if (attributes==null || attributes.containsServerTagOutsideOfAttributeValue) return toString();
		final StringBuilder sb=new StringBuilder();
		sb.append('<');
		if (toXHTML && startTagType==StartTagType.NORMAL) {
			sb.append(name);
		} else {
			int i=begin+startTagType.startDelimiterPrefix.length();
			final int nameSegmentEnd=i+name.length();
			while (i<nameSegmentEnd) {
				sb.append(source.charAt(i));
				i++;
			}
		}
		try {
			attributes.appendTidy(sb,getNextTag());
		} catch (IOException ex) {throw new RuntimeException(ex);} // never happens
		if (startTagType==StartTagType.NORMAL && getElement().getEndTag()==null && !HTMLElements.getEndTagOptionalElementNames().contains(name)) sb.append(" /");
		sb.append(startTagType.getClosingDelimiter());
		return sb.toString();
	}

	/**
	 * Generates the HTML text of a {@linkplain StartTagType#NORMAL normal} start tag with the specified tag name and {@linkplain Attributes#populateMap(Map,boolean) attributes map}.
	 * <p>
	 * The output of the attributes is as described in the {@link Attributes#generateHTML(Map attributesMap)} method.
	 * <p>
	 * The <code>emptyElementTag</code> parameter specifies whether the start tag should be an
	 * <a target="_blank" href="http://www.w3.org/TR/REC-xml#dt-eetag">empty-element tag</a>,
	 * in which case a slash is inserted before the closing angle bracket, separated from the name
	 * or last attribute by a single space.
	 * <p>
	 * <dl>
	 *  <dt>Example:</dt>
	 *  <dd>
	 *   <p>
	 *   The following code:
	 *   <blockquote class="code">
	 * <pre>
	 * LinkedHashMap attributesMap=new LinkedHashMap();
	 * attributesMap.put("name","Company");
	 * attributesMap.put("value","G\n00fcnter O'Reilly & Associ&eacute;s");
	 * System.out.println(StartTag.generateHTML("INPUT",attributesMap,true));</pre>
	 *   </blockquote>
	 *   generates the following output:
	 *   <blockquote class="code">
	 *    <code>&lt;INPUT name="Company" value="G&amp;uuml;nter O'Reilly &amp;amp; Associ&amp;eacute;s" /&gt;</code>
	 *   </blockquote>
	 *  </dd>
	 * </dl>
	 *
	 * @param tagName  the name of the start tag.
	 * @param attributesMap  a map containing attribute name/value pairs.
	 * @param emptyElementTag  specifies whether the start tag should be an <a target="_blank" href="http://www.w3.org/TR/REC-xml#dt-eetag">empty-element tag</a>.
	 * @return the HTML text of a {@linkplain StartTagType#NORMAL normal} start tag with the specified tag name and {@linkplain Attributes#populateMap(Map,boolean) attributes map}.
	 * @see EndTag#generateHTML(String tagName)
	 */
	public static String generateHTML(final String tagName, final Map<String,String> attributesMap, final boolean emptyElementTag) {
		final StringBuilder sb=new StringBuilder();
		sb.append('<').append(tagName);
		try {
			Attributes.appendHTML(sb,attributesMap);
		} catch (IOException ex) {throw new RuntimeException(ex);} // never happens
		if (emptyElementTag)
			sb.append(" />");
		else
			sb.append('>');
		return sb.toString();
	}

	public String getDebugInfo() {
		final StringBuilder sb=new StringBuilder();
		appendDebugTag(sb);
		sb.append(' ');

⌨️ 快捷键说明

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