📄 litexmlelement.java
字号:
result.append( target.charAt( current ) );
current++;
continue;
}
char [] sub = new char[ terminusAt - current + 1 ];
target.getChars(current, terminusAt + 1, sub, 0 );
String escaped = new String( sub );
if( "&".equals( escaped ) ) {
result.append( '&' );
current += 4;
}
else if ( "<".equals( escaped ) ) {
result.append( '<' );
current += 3;
}
else if ( ">".equals( escaped ) ) { // for compatibility with SGML. We dont encode these
result.append( '>' );
current += 3;
}
else if ( escaped.startsWith( "&#" ) ) {
String numericChar = escaped.substring( 2, escaped.length() - 1 );
// is it &#; ?
if( numericChar.length() < 1 ) {
result.append( target.charAt( current ) );
current++;
continue;
}
// is it hex numeric
if( numericChar.charAt( 0 ) == 'x' ) {
numericChar = numericChar.substring( 1 );
// is it &#x; ?
if( numericChar.length() < 1 ) {
result.append( target.charAt( current ) );
current++;
continue;
}
try {
char asChar = (char) Integer.parseInt( numericChar.toLowerCase(), 16 );
result.append( asChar );
current += escaped.length();
} catch( NumberFormatException badref ) {
// it was bad, we will just skip it.
result.append( target.charAt( current ) );
current++;
}
continue;
}
// its base 10
try {
char asChar = (char) Integer.parseInt( numericChar, 10 );
result.append( asChar );
current += escaped.length();
} catch( NumberFormatException badref ) {
// it was bad, we will just skip it.
result.append( target.charAt( current ) );
current++;
}
continue;
}
else {
// if we get here then we didn't know what to do with the
// entity. so we just send it unchanged.
result.append( target.charAt( current ) );
current++;
continue;
}
current++;
}
return result;
}
/**
* Given a StringBuffer find all occurances of characters which must be
* escaped and convert them to their escaped equivalents.
*
* @param target The stringbuffer which will be encoded in place.
*
**/
protected void encodeEscaped( StringBuffer target ) {
int current = 0;
while( current < target.length() ) {
if( '&' == target.charAt( current ) ) {
target.insert( current+1, "amp;" );
current += 5;
continue;
}
else if( '<' == target.charAt( current ) ) {
target.setCharAt( current, '&' );
target.insert( current + 1, "lt;" );
current += 4;
continue;
}
else
current++;
}
}
/**
* Returns an enumerations of the attributes assosicated with this object.
* Each element is of type Attribute.
*
* @return Enumeration the attributes associated with this object.
*
*/
public Enumeration getAttributes() {
Vector results = new Vector();
if( null != uninserted )
throw new IllegalStateException( "This element has not been added." );
// find the start of the first attribute
int current = loc.startTag.start + 1;
while( -1 == "\n\r\t />".indexOf( doc.docContent.charAt(current) ) )
current++;
// loop and add attributes to the vector
while( current < loc.startTag.end ) {
tagRange nextAttr =
getAttributeLoc( null, new charRange( current, loc.startTag.end ) );
if( !nextAttr.isValid() )
break;
//PDA requirements 19.02.2002
//java.util.Vector.add(Object obj) -> java.util.Vector.addElement(Object obj)
//results.add( new Attribute( this,
results.addElement( new Attribute( this,
//PDA requirements 19.02.2002
doc.docContent.substring(nextAttr.startTag.start, nextAttr.startTag.end + 1 ),
doc.docContent.substring(nextAttr.body.start, nextAttr.body.end + 1) ) );
current = nextAttr.endTag.end + 1;
}
return results.elements();
}
/**
* Returns the tagRange of the next attribute contained in the range
* provided. The tag range returned consists of the startTag indicating
* the location of the name, body indicating the location of the value and
* endTag indicating the location of the final quote delimiter.
*
* @param name Name to match. null means match any name.
* @param inRange the limits of the locations to scan.
* @return tagRange containing the location of the next attribute
**/
private tagRange getAttributeLoc( String name, charRange inRange ) {
tagRange result = new tagRange();
int current = inRange.start;
do {
// skip the whitespace
while( -1 != "\n\r\t >".indexOf( doc.docContent.charAt(current) ) )
current++;
int equalsAt = doc.docContent.indexOf( '=', current );
// make sure there is an equals
if( (-1 == equalsAt) || (equalsAt >= inRange.end ) )
return result;
// get the name
result.startTag.start = current;
result.startTag.end = equalsAt - 1;
// get the quote char we must match
char requiredQuote = doc.docContent.charAt(equalsAt + 1);
// make sure its a valid quote
if( ('\'' != requiredQuote) && ('\"' != requiredQuote) )
return result;
// find the next occurance of this quote
int nextQuote = doc.docContent.indexOf( requiredQuote, equalsAt + 2 );
// make sure the quote is in a good spot.
if( (-1 == nextQuote) || (nextQuote >= inRange.end ) )
return result;
result.body.start = equalsAt + 2;
result.body.end = nextQuote - 1;
result.endTag.start = nextQuote;
result.endTag.end = nextQuote;
// check if the name matches.
if( (null != name) &&
!name.equals( doc.docContent.substring( result.startTag.start, result.startTag.end + 1) ) )
result.startTag.start = -1;
current = nextQuote + 1;
} while( (current < inRange.end) && (!result.isValid()) );
return result;
}
/**
* Adds an attribute with the given name and value. Some implementations
* may support only a single value for each distinct name. Others may
* support multiple values for each name. If the value being provided
* replaces some other value then that value is returned otherwise null
* is returned.
*
* @param name name of the attribute.
* @param value value for the attribute.
* @return String containing previous value for this name if the value
* is being replaced otherwise null.
*/
public String addAttribute(String name, String value) {
if( null != uninserted )
throw new IllegalStateException( "This element has not been added." );
if( null == name )
throw new IllegalArgumentException( "name must not be null" );
if( null == value )
throw new IllegalArgumentException( "value must not be null" );
// skip past the name portion
int current = loc.startTag.start + 1;
while( -1 == "\n\r\t />".indexOf( doc.docContent.charAt(current) ) )
current++;
// find out if there was a previous value for this name
tagRange oldAttr = getAttributeLoc( name,
new charRange(current, loc.startTag.end) );
String oldValue = null;
// choose which kind of quote to use
char usingQuote = ( -1 != value.indexOf( '"' ) ) ? '\'' : '\"';
// make sure we can use it.
if( -1 != value.indexOf( '\'' ) )
throw new IllegalArgumentException( "Value contains both \" and \'" );
// build the new attribute string
StringBuffer newStuff = new StringBuffer( " " );
newStuff.append( name );
newStuff.append( "=" );
newStuff.append( usingQuote );
newStuff.append( value );
newStuff.append( usingQuote );
// add it in.
if( !oldAttr.isValid() ) {
// we aren't replacing an existing value
doc.docContent = doc.docContent.substring( 0, loc.startTag.end ) +
newStuff +
doc.docContent.substring( loc.startTag.end );
// move all doc locations which follow this one based on how much we
// inserted.
doc.adjustLocations( loc.body.start, newStuff.length() );
// we have to adjust the locations first or the startTag.end would get
// updated twice.
loc.startTag.end += newStuff.length();
}
else {
// we are replacing an existing value
oldValue = doc.docContent.substring( oldAttr.body.start, oldAttr.body.end + 1 );
doc.docContent =
doc.docContent.substring( 0, oldAttr.startTag.start ) +
newStuff +
doc.docContent.substring( oldAttr.endTag.end + 1 );
int delta = newStuff.length() - (oldAttr.endTag.end - oldAttr.startTag.start + 1);
// move all doc locations which follow this one based on how much we
// inserted or deleted.
doc.adjustLocations( loc.body.start, delta );
// adjustLocations may have had an effect on loc.startTag.end
// depending on what was done. This ensures it has the right value.
loc.startTag.end = loc.body.start - 1;
}
if( !loc.isValid() )
throw new IllegalStateException( "Document is damaged" );
return oldValue;
}
/**
* Adds an attribute with the given name and value. Some implementations
* may support only a single value for each distinct name. Others may
* support multiple values for each name. If the value being provided
* replaces some other value then that value is returned otherwise null
* is returned.
*
* @param newAttrib new attribute.
* @return String containing previous value for this name if the value
* is being replaced otherwise null.
*/
public String addAttribute(Attribute newAttrib) {
return addAttribute( newAttrib.getName(), newAttrib.getValue() );
}
/**
* Returns a single attribute which matches the name provided. If no such
* named attribute exists then null is returned. For impelementations of
* this interface which support multiple values for each name only the
* first value will be returned. To access all values for a name you must
* use getAttributes.
*
* @return Attribute the attributes matching the given name.
*
*/
public Attribute getAttribute(String name) {
if( null != uninserted )
throw new IllegalStateException( "This element has not been added." );
// skip past the name portion
int current = loc.startTag.start + 1;
while( -1 == "\n\r\t />".indexOf( doc.docContent.charAt(current) ) )
current++;
// find the attribute matching this name
tagRange attr = getAttributeLoc( name, new charRange(current, loc.startTag.end) );
if( !attr.isValid() )
return null;
// build the object
return new Attribute( this,
doc.docContent.substring(attr.startTag.start, attr.startTag.end + 1 ),
doc.docContent.substring(attr.body.start, attr.body.end + 1) );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -