Метод addText
Метод addText, приведенный в листинге 4.20, вызывается некоторыми другими методами из класса ProductFormatter. Ему передается объект StringBuffer, в который добавляется текст. Параметр name определяет, какой именно текст требуется добавить, а элемент Element соответствует некоторому товару в каталоге. Целое число, являющееся значением параметра name, управляет точками перехода в инструкции switch.
Листинг 4.20. Метод addText (ProductFormatter.java)
// заметим, что в большинстве случаев нам нужно
// значение узла
private void addText(StringBuffer sb, String name, Element el ){
Object obj = fieldHash.get( name );
if( obj == null ){
sb.append( "no " + name + " found " ); return ;
}
switch( ((Integer)obj).intValue()){
case 0 : // "id",
addID( sb, el ); break ;
case 1 : // "keywords",
case 2 : // "prname", product name
addProductName( sb, el ); break ;
case 3 : // "price"
addPrice( sb, el ); break ;
case 4 : // "author",
addAuthor( sb, el ); break ;
case 5 : // "artist",
addArtist( sb, el ); break ;
case 6 : // "description",
addExtendedText( sb, el ); break ;
case 7 : // "image",
addImageTag( sb, el ); break ;
case 8 : // "caption"
addExtendedText( sb, el ); break ;
case 9 : // "quantity_in_stock",
case 10 : // "onsale_date"
}
}
Различные методы, вызываемые методом addText, приведены в листингах 4.21 и 4.22. Эти методы извлекают тот или иной текст из элемента product и добавляют его в Stri ngBuffer.
Листинг 4.21. Различные методы, вызываемые методом addText (ProductFormatter.java)
// Элемент е - это товар <product>
private void addID(StringBuffer sb, Element e ){
String id = e.getAttribute("id" );
sb.append("product code: ");
if( id.length()== 0 ){ sb.append("not assigned");
}
else { sb.append( id );
}
}
// element is either a <product> or <name> as child of a product
private void addProductName( StringBuffer sb, Element e){
if( !e.getNodeName().equals("name") ){
NodeList nl = e.getElementsByTagName( "name" );
e = (Element) nl.item(0);
}
sb.append( getChildrenText( e ) );
}
// element is <author> tag
private void addAuthor( StringBuffer sb, Element e){
NodeList nl = e.getElementsByTagName( "name" );
sb.append( getChildrenText( (Element) nl.item(0)) );
}
private void addArtist( StringBuffer sb, Element e){
NodeList nl = e.getElementsByTagName( "name" );
sb.append( getChildrenText((Element) nl.item(0)) );
}
// example <author><name>Christoph Minwich</name></author>
// known to have price
private void addPrice( StringBuffer sb, Element e ){
NodeList nl = e.getElementsByTagName( "price" );
sb.append("price ea = ");
sb.append( nl.item(0).getFirstChild().getNodeValue() );
}
Служебный метод getChildrenText, приведенный в листинге 4.22, собирает вместе текст всех дочерних узлов данного элемента.
Листинг 4.22. Служебный метод getChildrenText (ProductFormatter.java)
private String getChildrenText( Element e ){
StringBuffer sb = new StringBuffer();
NodeList nl = e.getChildNodes();
for( int i = 0 ; i < nl.getLength() ; i++ ){
sb.append( nl.item(i).getNodeValue() );
}
return sb.toString();
}
Метод addlmageTag, приведенный в листинге 4.23, использует информацию из тега XML <iraage>. Ниже приводится пример из файла catalog.xml:
<image format="gif" width="234" height="4Q0"
src="images/covers/pi ants.gif">
<caption>
<paragraph>This is the cover from the
first edition.</paragraph>
</caption>
</image>
Помимо создания тега <img>, который вставляет в HTML-страницу изображение, этот метод также проводит анализ и отображает подпись к изображению.
Листинг 4.23. Метод, создающий теги изображения (ProductFormatter.java)
private void addImageTag( StringBuffer sb, Element img ){
String format = img.getAttribute("format");
String width = img.getAttribute("width");
String height = img.getAttribute("height");
String src = img.getAttribute("src");
String desc = "image ";
sb.append("<img src=\"");
// detect option for image source to point off site
if( !src.toUpperCase().startsWith("HTTP")){
sb.append(resourcePath );
}
if( sb.charAt( sb.length() - 1 ) == '/' &&
src.charAt(0) == '/' ){
sb.append( src.substring(1) );
}
else sb.append( src ) ;
sb.append( "\" alt=\"" );
NodeList imgNL = img.getElementsByTagName("caption");
if( imgNL.getLength() > 0 ){
sb.append( desc );
// addText(sb, "caption", (Element) imgNL.item(0) );
}
else sb.append( desc );
sb.append( "\" width=\"" );
sb.append( width ); sb.append( "\" height=\"" );
sb.append( height ); sb.append( "\" >" );
//NodeList imgNL = img.getElementsByTagName("caption") ;
if( imgNL.getLength() == 0 ) return ;
Element caption = (Element) imgNL.item(0);
addText( sb, "caption", caption );
return ;
}
Формат нашего XML-каталога допускает использование стиля running_text в подписях и описаниях товаров. Методы addExtendedText и doExtendedTextEl ement, показанные в листинге 4.24, могут объединить весь текст описания или подписи с соответствующей разметкой HTML, чтобы создать абзац или назначить начертание этого текста (курсив или полужирный шрифт).
Листинг 4.24 Метод addExtendedText()
// одним из вариантов стиля является
// <paragraph>, простой текст
private void addExtendedText( StringBuffer sb, Element e ){
NodeList nl = e.getChildNodes();
int ct = nl.getLength();
// sb.append("child count " + ct + brcrlf );
for( int i = 0 ; i < ct ; i++ ){
Node n = nl.item(i);
switch( n.getNodeType() ){
case Node.TEXT_NODE :
sb.append( n.getNodeValue().trim() ); break ;
case Node.ELEMENT_NODE :
Element en = (Element) n ;
// sb.append("Element Name " + en.getNodeName() );
doExtendedTextElement(en.getNodeName(), sb, en );
break ;
default :
sb.append("default Name " + n.getNodeName() );
sb.append(" Value " + n.getNodeValue() );
}
sb.append(' ' ); // because values get trimmed
//sb.append( brcrlf );
}
}
//
private void doExtendedTextElement( String name, StringBuffer sb, Element e){
if( name.equals("paragraph") ){
sb.append("<p>"); addExtendedText( sb, e );
sb.append("</p>");
}
else if( name.equals("italics")){
sb.append("<i>" ); addExtendedText( sb, e );
sb.append(" </i>");
}
else if( name.equals("bold")){
sb.append("<b>" ); addExtendedText( sb, e );
sb.append(" </b>");
}
else { addExtendedText( sb, e );
}
}
public String toString()
{ StringBuffer sb = new StringBuffer("ProductFormatter ");
return sb.toString();
}
}