JavaAn Improved Approach for Creating SVG/XML Code and SVG/XML DOM Nodes using...

An Improved Approach for Creating SVG/XML Code and SVG/XML DOM Nodes using Java

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Java Programming Notes # 2214


Preface

General

This is the second lesson in a series designed to teach you how to write
servlets to produce SVG code that will be rendered in graphic form by an
SVG-compatible browser.

An SVG graphics library

In the previous lesson titled "Java JAXP, Creating graphics using Java and
SVG" (see Resources) I taught you how write your
own SVG graphics library to eliminate, or at least alleviate the requirement to
write raw XML code or raw JAXP DOM code, making it possible for you to produce
SVG output simply by making typical Java method calls.

At the end of the previous lesson, I promised that this lesson would teach
you how to take what you learned in the previous lesson and apply it to the
generation of XHTML files containing in-line SVG/XML code.  I also promised that
this lesson would teach you how to apply that knowledge to the writing of
servlets that produce XHTML output containing in-line SVG/XML code.  Upon
further consideration, however, I decided to delay that material until the
lesson following this one.

Upgrading the SVG graphics library

In this lesson, I will provide two more methods for the SVG graphics library
that make it even easier to write servlets to produce SVG output.  The
first method eliminates the frustration of dealing with the escape sequences
required for the quotation marks that surround attribute values in XML. 
The second method makes it possible to create a general node in the DOM tree
being used to represent an SVG graphic.

Viewing tip

I recommend that you open another copy of this document in a separate
browser window and use the following links to easily find and view the figures
and listings while you are reading about them.  You may also find it useful
to open a third browser window at the Resources section near the end of the
document.  That will make it easy for you to open those resources when they
are mentioned in the text.

Figures

  • Figure 1. Svg07 screen output.
  • Figure 2. Recommended usage of the makeElement
    method.
  • Figure 3. Graphic output from Svg08.
  • Figure 4. Recommended usage of the makeNode
    method.

Listings

Supplementary material

I recommend that you also study the other lessons in my extensive collection
of online Java tutorials.  You will find a consolidated index at

www.DickBaldwin.com
.

General background information

According to the W3C

"SVG is a language for describing two-dimensional graphics in XML. SVG allows
for three types of graphic objects: vector graphic shapes (e.g., paths
consisting of straight lines and curves), images and text. Graphical objects can
be grouped, styled, transformed and composited into previously rendered objects.
The feature set includes nested transformations, clipping paths, alpha masks,
filter effects and template objects."

Not easy reading

The Scalable Vector Graphics (SVG) 1.1
Specification
is extensive.  Unfortunately, a person needs a fairly
strong background in XML to be able to understand much of the information in the
specification, thereby reducing the accessibility of that information to Java
programmers who lack such a background in XML.

Will present in a more understandable form

While I don’t claim to have expertise in XML, I do know enough about the
topic that I can usually make sense of the material provided in the SVG
specification.  One of my objectives for this series is to extract much of the important
information from the specification and to present it in such a way as to make it
accessible to Java programmers who lack a strong background in XML and who don’t
have the time available to gain that background knowledge.

The bottom line – great graphics in the browser

No experience with IE/SVG plug-in
Please note that because I am not a frequent user of Internet Explorer, I have
not installed and tested the SVG plug-in for IE.  The sample programs
in this series were tested using Firefox 1.5.  I have read, however,
that IE can be made SVG compatible by installing the plug-in.

The bottom line is that Java programs can be written to produce XML
output, which, when presented to an SVG rendering engine, (such as Firefox 1.5 or
IE 6 with the SVG plug-in installed)
, will cause the display of graphic material
in the following three categories:

  • Vector graphic shapes
  • Images
  • Text

As a practical matter, when combined with the use of servlets, this makes it
possible to display graphic material in the client area of a web browser that
competes favorably with the graphic material that can be displayed using the
Java 2D API in desktop applications. 

Preview

Escape sequences for quotation marks
Actually, it isn’t too difficult to write the code to create escape sequences
for quotation marks surrounding XML attributes.  What I find difficult
is to understand that code when I have to go back and make sense of it
later.

The program named Svg07

Despite your best intentions, when you are writing Java programs that produce
XML output, you must occasionally write an output statement that produces raw
XML code, often in the form of a very complex XML element having multiple
attributes.  One of the most frustrating things about writing Java code to
create elements in XML (also XHTML and HTML) is having to deal with the
escape sequences for the many required quotation marks that surround attribute
values. 

The program named Svg07 demonstrates a method that I will add to my
SVG graphics library, which can be used to easily create XML elements without
having to deal with those escape sequences.  The elements produced by the
method may or may not be empty, and may or may not have attributes.

The program named Svg08

The program named Svg08 uses a similar technique as Svg07 to deal with another issue that frequently
surfaces when using Java to create SVG graphics.  This issue has to do with
the accommodation of a very large number of possible attributes that can be
applied to each node in the DOM tree.

My original SVG graphics library

The previous lesson (see Resources) presented
a small proof-of-concept SVG graphics library that provided method calls
for the creation of the following DOM tree nodes:

  • A simple element with no attributes.
  • A linear gradient element.
  • An ellipse.
  • A circle.

Once the DOM tree representing a particular graphic image has been created,
it can easily be transformed into an output SVG file containing the XML code
required for rendering the graphic using an SVG rendering engine such as Firefox 1.5.

An expanded SVG graphics library

The next lesson in this series will expand my SVG graphics library to provide
method calls for all of the Basic
Shapes
in the SVG specification (see Resources), plus some other elements as well. 
This will include the following basic shapes:

  • rect
  • circle
  • ellipse
  • line
  • polyline
  • polygon

Many attributes for each shape

When programming with raw SVG/XML code, there are a dozen or more attributes that can
be applied to each shape when it is rendered.

A programmer calling a higher level method
to create a shape, (such as an ellipse for example), would usually prefer not to have to routinely deal
with more than a dozen attributes for each ellipse.  That programmer would
probably prefer to routinely deal with only those attributes that are most
likely to be different from one ellipse to the next.

Therefore,
the methods in my SVG graphics library attempt to default most of the attributes
and require the programmer to deal only with the attributes that are most likely
to be different from one instance of the shape to the next.

Must provide a fallback position

Having taken that approach, however, it is necessary to provide the
programmer with a method that can be used to create a shape dealing with
all or any combination of the available attributes.  The program named
Svg08
demonstrates an SVG graphics method that can be used to create a
general DOM tree node having any name and any number of attributes with any
attribute names and any String value for each attribute.  I will
also add this method to my SVG graphics library to be used in the next and all
subsequent lessons in this series.

This program produces an SVG file as its output.  The file can be
rendered using Firefox 1.5.  Note, however, that the method is equally appropriate for
use in producing XHTML output code, which I plan to explain in the next lesson.

Discussion
and sample code

The Svg07 program

Description of the program

As I mentioned earlier, one of the most frustrating things about using Java
to create raw code elements in XML, XHTML, or HTML is having to deal with the
escape sequences for the many required quotation marks that surround attribute
values.  This program demonstrates a method that can be used to easily
create raw XML code elements without having to deal with those escape sequences. 
The elements produced by the method may or may not be empty, and may or may not
have attributes.

Color and boldface
The program named Svg07 does not produce the color and boldface shown in
Figure 1.  I added those features manually to make it easier to refer
back to the contents of Figure 1 later.


Svg07 screen output

The screen output of the program named Svg07 is shown in Figure 1. I will refer back to this screen output as I discuss the program code.

Figure 1. Svg07 screen output.

Demo empty element with attributes.
<ElementName color="Color.RED" width="10" height="20" />

Demo empty element with no attributes.
Probably doesn't make any sense.
<ElementName />

Demo non-empty element with attributes.
<ElementName color="Color.RED" width="10" height="20" >
Content of element.
</ElementName>

Demo non-empty element with no attributes.
<ElementName >
Content of element.
</ElementName>

This program was tested using J2SE 5.0 and WinXP.

Will discuss in fragments

As is my custom, I will discuss and explain this program in fragments. 
(You can view the entire program in Listing 22 near the end of the lesson.)  The first fragment in Listing 1 shows the beginning of the class and the
beginning of the main method.

Listing 1. Beginning of the class named Svg07.

public class Svg07{
  public static void main(String argv[]){
    String name = "ElementName";
    System.out.println(
                   "Demo empty element with attributes.");

    String emptyElement = makeElement(true,name,
                         new String[]{"Color","Color.RED",
                                      "width","10",
                                      "height","20"});
    System.out.println(emptyElement);

No requirement to program using the escape sequence

The code in Listing 1 produces the first block of output text shown in Figure
1.  Note the correspondence between the values in the elements of the array
object of type String[] in Listing 1 and the attribute names and values
in the first block of output text in Figure 1.  Note also that there was no
requirement in Listing 1 to create string data using the escape sequence for
quotation marks as shown below:

"color="Color.RED" width="10" height="20""

Instead, each attribute name and each attribute value was specified as a
simple String in Listing 1, and the method named makeElement
produced the required output format shown in the first block of text in Figure
1.  While this method is very simple, it is also extremely useful. 
(Sometimes the most useful things are the simplest.)

The method named makeElement

At this point, I am going to put the main method on the back burner
and explain the method named makeElement.

As mentioned earlier, one of the most frustrating things about using Java to
create raw elements in XML, XHTML, or HTML is having to deal with the escape
sequences for the many required quotation marks that surround attribute values.
The method named makeElement constructs an element, which may or may not
have attributes. Also, the element may or may not be empty.

The user of this method does not have to deal with the required quotation
marks surrounding attribute values and the corresponding escape sequences.


Recommended usage of the makeElement method

The recommended usage of the makeElement method is shown in Figure 2. 

Figure 2. Recommended usage of the makeElement method.

String newElement = makeElement(
                         true/false,
                         name,
                         new String[]{"name","value",
                                      "name","value",
                                      "name","value",
                                      ...
                                      "name","value",
                                     });

(Note that the ellipses (…) in Figure 2 indicate that any number of
name/value pairs is allowed.)

The first parameter to the method

The first parameter must be true if the element is empty and false
if the element is not empty.

If the first parameter is true, the element is
sealed off in the required manner for an empty element (see the end of the
black boldface text in the first block of text in Figure 1)
.

If the first parameter
is false, the method returns the complete start tag for the element but does not
return a complete element.  (See the black boldface text in the third
and fourth blocks of text in Figure 1.)
   In this case, it is the responsibility of the calling method to
provide the content and the end tag for the element.  (See
the red text in the third and fourth blocks of text in Figure 1.)

The second parameter to the method

The second parameter to the
makeElement method must be a String that specifies the name of the element.

The third parameter to the method

The third
parameter to the makeElement method must be a reference to an array object of type String[]
or null.

This array must contain an even number of elements.  Each pair of array elements
constitutes the name and the value of an attribute, in the order name, value,
name, value,
etc.

Start tag for an element with no attributes
Although this is one of the possible combinations, it is probably easier to
hard-code such a start tag in the Java code rather than to make a call to
the makeElement method.

If the reference to the array object is null and the first
parameter is false, the method returns the start tag for an element that has no
attributes and is not empty. (See the black boldface text in the fourth block
of text in Figure 1.)
 

An empty element with no attributes
This combination probably won’t be heavily used because there isn’t a lot of
demand for XML elements that are empty with no attributes.

If the reference to the array object is null and the first parameter is
true, the method returns a complete empty element with no attributes (see the
black boldface text in the second block of text in Figure 1)

The most useful combinations

Because the purpose of the method is to make it easier to deal with the
quotation marks that must surround attribute values in XML elements, the most
useful combinations are represented by the first and third blocks of text in
Figure 1, which are respectively:

  • An empty element with attributes.
  • An element with attributes that is not empty.


The beginning of the makeElement method

The method named makeElement begins in Listing 2.

Listing 2. The beginning of the makeElement method.

  static String makeElement(boolean empty,
                            String elementName,
                            String[] data){

    //Begin constructing the start tag.
    String element = "<" + elementName + " ";
The StringBuffer class
Another, and possibly more efficient way to construct the String object
that represents the element would be to use the append method of
the StringBuffer class.

The code in Listing 2 instantiates a String object, which consists of
a left angle bracket concatenated with the name of the element.  This
object will be used to create a succession of new String objects
containing attribute names and values as the method executes.


Dealing with elements that have no attributes

Listing 3 deals with elements that have no attributes on the basis of the
values of the first and third parameters.

Listing 3. Dealing with elements that have no
attributes.

    if((empty==false) && (data == null)){
      //Return a complete start tag.
      return element + ">";
    }else if((empty==true) && (data == null)){
      //Return a complete empty element.
      return element + "/>";
    }//end if

The code in Listing 3 is straightforward.  Because there are no
attributes, no further processing within the method is required.  Depending
on the combination of parameter values, this code will return the String
object shown by the black boldface text in either the second block of text or
the fourth block of text in Figure 1.


Processing the attributes

The code in Listing 4 is executed when the third parameter is not null,
meaning that there are attribute names and values in the array object referenced by the value
of the third parameter.

Listing 4. Processing the attributes.

    for(int cnt=0;cnt<data.length;cnt+=2){
      String name = data[cnt];
      String value = data[cnt+1];
      element += name + "=" + """ + value + "" ";
    }//end for loop

The code in Listing 4 extracts the values from the array in pairs and uses
those pairs of values to successively create extended String objects that
are formatted properly for the specification of XML element attribute names and
values.  (See the black boldface text in the first and third blocks of
text in Figure 1.)
  Note that the code in Listing 4 uses the escape
sequence to properly surround the attribute values with quotation marks, thus
relieving the using programmer of the requirement to perform this task.


Decision time: empty element or non-empty element

When the loop in Listing 4 terminates, the element has been constructed out
to the point where it is necessary to decide whether to seal it off as an empty
element (/>) or to seal it off as the end of the start tag (>) for an element
that is not empty.  That decision is made by the code in Listing 5 on the
basis of the value of the first parameter.

Listing 5. Decision: empty element or non-empty
element.

    if(empty){
      //Terminate the element appropriately for an
      // empty element. A complete empty element will
      // be returned.
      element += "/>";
    }else{
      //End the start tag for an element that is not
      // empty. In this case, only the start tag will
      // be returned.  The calling program must provide
      // the content for the element as well as the end
      // tag for the element.
      element += ">";
    }//end else
    
    return element;
  }//end makeElement

The code in Listing 5 is straightforward and shouldn’t require further
explanation.

Return the element and terminate the method

Listing 5 also returns a reference to the String object containing the
newly-constructed element and terminates the method named makeElement.


Remaining code in the main method

Now that you understand how the method named makeElement works, you
shouldn’t have any difficulty understanding the remaining code in the main
method, which is shown in Listing 6.

Listing 6. Remaining code in the main method.

    System.out.println();
    System.out.println(
                "Demo empty element with no attributes.");
    System.out.println(
                      "Probably doesn't make any sense.");
    emptyElement = makeElement(true,name,null);
    System.out.println(emptyElement);

    System.out.println();
    System.out.println(
               "Demo non-empty element with attributes.");
    String elementStartTag = makeElement(false,name,
                         new String[]{"Color","Color.RED",
                                      "width","10",
                                      "height","20"});
    System.out.println(elementStartTag);
    System.out.println("Content of element.");
    //Create end tag for element
    System.out.println("</" + name + ">");

    System.out.println();
    System.out.println(
            "Demo non-empty element with no attributes.");
    elementStartTag = makeElement(false,name,null);
    System.out.println(elementStartTag);
    System.out.println("Content of element.");
    //Create end tag for element
    System.out.println("</" + name + ">");

  }// end main()

The code in Listing 6 calls the makeElement method three times to
produce the screen output shown in Figure 1.  You should have no difficulty
correlating the code in Listing 6 with the screen output shown in Figure 1.

Displayed on the screen for illustration

For illustration purposes, this program has simply used a println
statement to display the XML elements produced by the makeElement method
on the screen.  In future lessons, those elements will either be written
into SVG files as part of the SVG code required to render a graphic image, or
sent from a servlet to a browser as part of the SVG code produced by the
servlet.

The Svg08 program


Graphic output from Svg08

Before getting into the details of the program code for the program named
Svg08
, I want to show you the
graphic output from this program and explain what it mean.  That output is
shown in Figure 3.

Figure 3. Graphic output from Svg08.

The first way to draw an ellipse

Basically, this program illustrates three different ways to use the methods
in my SVG graphics library to draw an ellipse.  The first way is to call
the method named makeEllipse, providing attribute values for the
coordinates that define the center of the ellipse, the width of the ellipse, and
the height of the ellipse, and accept the default attribute
values for all of the other attributes.  This approach resulted in the black ellipse at
the top of Figure 3.  As you can see, this ellipse is completely opaque,
and the blue line beneath it does not show through.

The second way to draw an ellipse

The second way to draw an ellipse is to do the same thing as above, but to
follow that up by making two successive calls to the setAttribute method
to set the style attribute to fill:red, and to set the opacity
attribute to 0.6, (or 60-percent opaque).  This resulted in
the pink ellipse in the center of Figure 3, with the white background and the
wide blue line beneath the ellipse showing through.

The third way to draw an ellipse

The third way to draw an ellipse is to call the makeNode method to
draw an ellipse with the following attributes names and values:

  • cx: 110 (coordinate of center along the x-axis)
  • cy 300 (coordinate of center along the y-axis)
  • rx: 100 (radius along the x-axis)
  • ry: 40 (radius along the y-axis)
  • style: fill:green (fill color for the ellipse)
  • opacity: 0.6 (opacity attribute value)
  • transform: translate(110,300) rotate(15) translate(-110,-300)

This resulted in the rotated green ellipse at the bottom of Figure 3.

The first four attributes in the above list are the same attributes for which
the values were set for the black ellipse (but with different attribute
values)
.

The first six attributes in the above list are the same attributes for which
the values were set for the red ellipse (again with different attribute
values)
.

The last attribute in the above list was an extra attribute that was set on
the third (green) ellipse to cause it to be rotated by 15 degrees clockwise
about its center.  This attribute was not set for either the black ellipse
or the red ellipse.

A bit of trivia
Although I never realized it until just this moment, the word ellipses can
describe either three
spaced periods indicating the omission of text
or the
plural of ellipse.

Other graphic elements

In addition to the three ellipses that were drawn by this program, a
wide blue line was drawn underneath the three ellipses in order to demonstrate the transparency that
results from setting the opacity attribute value to less than 1.0.

Also, a black border, one pixel wide, was drawn to outline the canvas on which
the ellipses and the line were drawn.

Description of the program

The purpose of this program is to demonstrate the use of a graphics
method named makeNode that can be used to create a general DOM tree node having
any name and any number of attributes with any attribute names and any String
values for the attributes.

The program creates a DOM tree describing the graphic image shown in Figure 3
in SVG format.  Then the program transforms the DOM tree into raw XML code
and writes the XML code out into an XML file named junk.svg.

The program illustrates three different ways to use the methods of the SVG
graphics library to draw ellipses having different attribute values. The output
file produced by this program can be rendered by loading it into Firefox 1.5.

The program was tested using J2SE 5.0, Firefox v1.5.0.8, and WinXP.

Will discuss in fragments

As before, I will present and explain the program in fragments.  (You
can view the entire program in Listing 23 near the end of the lesson.)

The getDocument method
The method named getDocument was explained in an earlier lesson. 
That explanation won’t be repeated here.

The first fragment is shown in Listing 7.  This fragment shows the
beginning of the class and the main method, along with the beginning of
the code required to create the DOM tree. 

Listing 7. Begin creating the DOM tree.

public class Svg08 {

  public static void main(String[] args){

    //Begin by creating a DOM tree that represents the XML
    // code that will be rendered to produce the image of
    // interest.

    //Get the Document object.
    Document document = SvgGraphics.getDocument();


Create the root node named svg

Listing 8 calls the makeNode method to create the root node named
svg
and to append it to the document.

Listing 8. Create the root node named svg.

    Element svg = SvgGraphics.makeNode(
        document,
        null,//parent
        "svg",//node type
        new String[]{"xmlns","http://www.w3.org/2000/svg",
                     "version","1.1",
                     "width","220",
                     "height","440",
                     "position","absolute",
                     "top","0",
                     "left","0",
                    });//end makeNode method

For this special case where the new node needs to be a child of the document, null is passed as the second parameter
(that specifies the
parent)
.  Otherwise, a reference to the actual parent node should be passed as
the
second parameter.

With the exception of the attributes named xmlns and position,
you can probably pretty well surmise what the purpose of each attribute is. 
I will leave it as an exercise for the reader to go to the SVG specification
(see Resources)
to learn about those attributes.

The makeNode method

At this point, I am going to put the discussion of the main method on
the back burner while I present and explain the makeNode method.

The purpose of this method is to create a general node having any name and
any number of attributes with any attribute names and any String values
for the attributes.


Recommended usage of the makeNode method

Figure 4 shows an example of the recommended usage for the makeNode
method.

Figure 4. Recommended usage of the makeNode method.

    Element abc = SvgGraphics.makeNode(
                      document,
                      def,//parent could be null
                      "ghi",//node type
                      new String[]{"name","value",
                                   "name","value",
                                   ...
                                   "name","value",
                                  });//end makeNode method

The first parameter is a reference to the document to which the new node
belongs

The second parameter is a reference to the parent node to which this node is
to be appended so as to become a child of that node.  If this parameter is
null, the new node is appended to the document.  Otherwise, it is appended
to the specified parent node.

The third parameter is a String that specifies the type of the new node.

Reference to a String array object

The fourth parameter must be a reference to an array object of type String
or it must be null.  This array must contain an even number of elements. 
Each pair of elements constitutes the name and the value of an attribute, in the
following order: name, value, name, value, etc.  (Any number of
name/value pairs is allowed.)

Referring back to Listing 8, you see a call to the makeNode method to
create a new node of type svg and append it to (make it a child node
of)
the document node.

A reference to an array object of type String[] was passed as the
fourth parameter.  The array object in Listing 8 contained seven different pairs of
strings specifying the attribute names and corresponding attribute values for
seven different attributes.

Note the values of the width, height, top,
and left attributes in Listing 8.  Basically, these values specify the location and
dimensions of the canvas upon which the ellipses will be drawn.  These
values will
become important when I return to the discussion of the code in the main
method.


Beginning of the makeNode method

Listing 9 shows the beginning of the makeNode method, including the
creation of the new node of type Element.  The node is bare at
this point, but will be dressed up to contain attribute nodes, etc., as the execution of the method progresses.

Listing 9. Beginning of the makeNode method.

  static Element makeNode(Document document,
                          Element parent,
                          String nodeType,
                          String[] data){
  
    Element element = 
                (Element)document.createElement(nodeType);


Append new node to its parent

Listing 10 calls the appendChild method, to cause the new node to
become a child node of the specified parent.

Listing 10. Append new node to its parent.

    if(parent == null){
      //For the special case of parent equal to null,
      // append the new node to the document.
      document.appendChild(element);
    }else{
      //Otherwise, append the new node to the specified
      // parent.
      parent.appendChild(element);
    }//end else

For the special case where the parent is specified as null, the new node is
appended to the document.  Otherwise, it is appended to the specified
parent node.


Nodes that have no attributes

Listing 11 deals with the case where the reference to the array object is
null, indicating that this new node has no attributes.

Listing 11. Nodes that have no attributes.

    //Deal with elements that have no attributes.
    if(data == null){
      return element;
    }//end if

For this case, the node that was created in Listing 10 and appended to its
parent in Listing 11 is all that is required.  Therefore, the code in
Listing 11 simply returns a reference to that node and the method terminates.


Processing the attribute names and values

The for loop in Listing 12 extracts each attribute-name/value pair
from the array object and uses that information to set an attribute on the new
node with a matching name and a matching value.

Listing 12. Processing the attribute names and
values.

    
    for(int cnt=0;cnt<data.length;cnt+=2){
      String name = data[cnt];
      String value = data[cnt+1];
      element.setAttribute(name,value);
    }//end for loop
    
    return element;
  }//end makeNode

At this point, you could set an attribute on the node having just about any
name and just about any String value on the new node.  However, in
order for an attribute to be effective in the ultimate rendering of the graphic
image, the name and value must be included in the names and values that are allowed
by the SVG specification for an element of that type (see
Resources)
.

Return the new node

Listing 12 also returns a reference to the new node and terminates the
method.


Show outline of the canvas

Now, returning to the discussion of the main method and continuing
from where we left off in Listing 8, Listing 13 calls the makeNode method to
draw the rectangular outline at the edge of the drawing canvas shown in Figure
3.

Listing 13. Show outline of the canvas.

      Element outline = SvgGraphics.makeNode(document,
                                         svg,//parent
                                         "rect",//type
        new String[]{"x","0",
                     "y","0",
                     "width","220",
                     "height","440",
                     "fill","none",
                     "stroke","black",
                     "stroke-width","1",
                    });//end makeNode method

The attribute values

The earlier code in Listing 8 created the canvas at the location and with the
dimensions that I pointed out earlier.  Note that the
location and dimensions of the rectangular outline drawn by the code in Listing
13 matches the location and dimensions of the canvas created in Listing 8.

The fill attribute specifies what is to be used to fill the interior
of the rectangle, and in this case, "none" is specified.

The stroke attribute specifies information about the stroke
that forms the outline of the rectangle.  In this case it was simply
specified as "black."

The stroke-width attribute specifies the thickness of the stroke that
forms the outline of the rectangle.  In this case the width was specified
to be the width of a single pixel.


Create a group container named g

Listing 14 calls the makeNode method to create a non-visual node named
g.  This node will be the parent for a line and three ellipses. 
Although I won’t demonstrate it in this program, having assigned the three
visual components to the same group, it would be possible for me to manipulate
them as a group in various ways.

Listing 14. Create a group container named g.

    Element g = SvgGraphics.makeNode(document,
                                     svg,//parent
                                     "g",
                                     null);

Note that Listing 14 passes null in place of a reference to an array object
containing attribute name/value pairs.  As a result, the node named g
is constructed with no attributes.


Draw a blue line

Listing 15 draws the blue line shown in Figure 3 beginning at the upper left
corner of the canvas and extending to the lower right corner of the canvas. 
The line is 12 pixels wide.

Listing 15. Draw a blue line.

    Element line = SvgGraphics.makeLine(document,
                                        g,   //owner
                                        0,   //x1
                                        0,   //y1
                                        220, //x2
                                        440);//y2
    line.setAttribute("stroke","blue");
    line.setAttribute("stroke-width","12");
The makeLine method
Note that the makeLine method
is much less general than the makeNode method, which could also have been
used to draw this line.  The choice between the two is based on
programmer preference.

The drawing of the line is accomplished in three steps.  The first step is
to draw the line as a default black line one pixel wide by calling the makeLine
method, passing the coordinates for the beginning and end points of the line as
parameters to the method. 

The second step is to call the setAttribute method to change
the color from black to blue.

The third step is to call the setAttribute method again to change the line
width from one pixel to twelve pixels.

This is a case of originally drawing the image by calling a very specialized
method, and then supplementing that call by two successive calls to a general
method that can be used to set attribute values, one attribute at a time.

The makeLine method

Once again, let’s put the discussion of the main method on the back
burner while we take a look at the code in the makeLine method, which is
shown in its entirety in Listing 16.

Listing 16. The makeLine method.

  static Element makeLine(Document document,
                          Element parent,
                          int x1,
                          int y1,
                          int x2,
                          int y2){
    Element line  = 
                  (Element)document.createElement("line");
    parent.appendChild(line);
    line.setAttribute("x1",""+x1);
    line.setAttribute("y1",""+y1);
    line.setAttribute("x2",""+x2);
    line.setAttribute("y2",""+y2);
    line.setAttribute("stroke","black");
    line.setAttribute("stroke-width","1");
    return line;
  }//end makeLine

The parameter values

This method returns a reference to a line. The parameters x1 and y1
specify the starting point of the line.  The parameters x2 and y2
specify the end point of the line.  (The line could be rotated and
translated later to make it appear differently but that wasn’t done in this
case.)
  By default, the stroke is set to black one pixel wide.

There is nothing complicated in Listing 16, so it shouldn’t require further
explanation.


Draw the black ellipse

Returning now to the main method, Listing 17 calls the makeEllipse
method to draw the black ellipse at the top in Figure 3.

Listing 17. Draw the black ellipse.

    SvgGraphics.makeEllipse(document,//This document
                            g,//Owner
                            110,//Center x-coordinate
                            100,//Center y-coordinate
                            100,//Width
                            40); //Height

The call to the makeEllipse method in Listing 17 passes parameter
values for four of the attributes.  These four attributes, which are set by
the makeEllipse method, specify the location and size of the ellipse. The
ellipse is black because the attribute that controls the color was not set.

The makeEllipse method

The makeEllipse method is shown in its entirety in Listing 18.

Listing 18. The makeEllipse method.

  static Element makeEllipse(Document document,
                             Element parent,
                             int xCoor,
                             int yCoor,
                             int xRadius,
                             int yRadius){
    Element ellipse  = 
               (Element)document.createElement("ellipse");
    parent.appendChild(ellipse);
    ellipse.setAttribute("cx",""+xCoor);
    ellipse.setAttribute("cy",""+yCoor);
    ellipse.setAttribute("rx",""+xRadius);
    ellipse.setAttribute("ry",""+yRadius);
    return ellipse;
  }//end makeEllipse

This makeEllipse method returns a reference to an ellipse. The
xCoor
and yCoor parameters specify the center of the ellipse. The
xRadius
and yRadius parameters specify the width and height of the
ellipse respectively.  The code in
Listing 18 is straightforward and shouldn’t require further explanation.


Draw the red ellipse

Returning once more to the main method, Listing 19 draws the red
(pink)
ellipse in the middle of Figure 3.

Listing 19. Draw the red ellipse.

    Element ellipse2 = SvgGraphics.makeEllipse(
                           document,
                           g,//Owner
                           110,//Center x-coordinate
                           200,//Center y-coordinate
                           100,//Width
                           40); //Height
    ellipse2.setAttribute("style","fill:red");
    ellipse2.setAttribute("opacity","0.6");

As with the line that was drawn earlier, the red ellipse in Figure 3 was
drawn in three steps.  The first step was to call the makeEllipse
method to draw a black ellipse in the correct position with the correct shape.

The second step was to call the setAttribute method to change the
fill color from black to red.

The third step was to call the setAttribute method again to change the
opacity from the default value of 100-percent opaque to a new value of
60-percent opaque (0.6).


Draw the green rotated ellipse

The green rotated ellipse shown at the bottom of Figure 3 could have been
drawn using the same approach as for the red ellipse and adding one more call to
the setAttribute method to accomplish the rotation.  However,
instead of drawing it that way, as shown in Listing 20, the green ellipse was
drawn by calling the makeNode method, and passing all of the relevant
attribute names and attribute values as the contents of an array object.

Listing 20. Draw the green rotated ellipse.

    Element ellipse3 = SvgGraphics.makeNode(
      document,
      g,//parent
      "ellipse",//node type
      new String[]{"cx","110",
                   "cy","300",
                   "rx","100",
                   "ry","40",
                   "style","fill:green",
                   "opacity","0.6",
                   "transform","translate(110,300) "
                             + "rotate(15) "
                             + "translate(-110,-300)"
                  });//end makeNode method 
The transform attribute
The transform attribute can be used to perform a variety of transformations on
a shape, such as rotate, scale, translate, and skew.  See section 7 of
the SVG specification in Resources.

The makeNode method

If you examine the code in Listing 20 carefully, and compare it with the code
for the makeNode method in Listing 9 through Listing 12, you will see
that it draws a green ellipse with 60% opacity rotated by 15-degrees clockwise
relative to its center.

As I explained earlier, the makeNode method lets you set all, none, or
any combination of attribute values in order to take advantage of any combination
of available attributes with no assumptions being made about any of
the attributes. This is the most general of the three approaches presented and
discussed in this lesson.


Transform the DOM and write the output file

Listing 21 transforms the DOM tree into raw XML code and writes that XML code
into an output file named junk.svg

Listing 21. Transform the DOM and write the output file.

    SvgGraphics.transformTheDom(document,"junk.svg");

  }// end main()

The method named transformTheDom was explained in an earlier lesson. 
That explanation won’t be repeated here.

The end of the program

Listing 21 also signals the end of the main method and the end of the
program.

Run the program

I encourage you to copy the code from Listing 22 and Listing 23 into your text
editor, compile it, and execute it.  Then view the resulting SVG files in
Firefox 1.5, or some other suitable SVG rendering engine.  Experiment with the
code, making changes, and observing the results of your changes.

Above all, enjoy the process. Programming can be fun.

Summary

Continuing with the SVG graphics library from the previous lesson, I taught
you how to write a method that deals with the escape sequences required for the
quotation marks that surround attribute values in XML thereby making it much
easier to write Java code that generates XML code.

I also taught you how to write a method that makes it possible to create a
general node in the DOM tree being constructed to represent an SVG graphic,
making no prior assumptions about the number of attributes, the names of the
attributes, or the values of the attributes.

What’s next?

The next lesson in this series will show you how to take what you have learned in
this and the previous lesson and to apply that knowledge to the generation of
XHTML files containing in-line SVG/XML code.  The next lesson will also teach
you how to apply that knowledge to the writing of servlets that produce XHTML
output containing in-line SVG/XML code.

Future lessons will teach you how to write servlets that:

  • Produce XHTML output containing references to external SVG files, some
    of which are created on-the-fly during the execution of the servlet.
  • Create and re-use graphic elements.
  • Use SVG symbols.
  • Deal with stroke caps in SVG in comparison with similar caps in Java 2D.
  • Use the switch element in SVG.
  • Deal with bit-mapped images in SVG.
  • Deal with text in SVG.
  • Deal with other features such as animation in SVG.

Complete program listings


Complete listings of the programs discussed in this lesson are shown in
Listing 22 and Listing 23 below.

Listing 22. The program named Svg07.

/*File Svg07.java
Copyright 2006, R.G.Baldwin

One of the most frustrating things about using Java to
create elements in XML, XHTML, or HTML is having to deal
with the escape characters for the many required
quotation marks that surround attribute values.  This 
program demonstrates a method that can be used to easily 
create elements without having to deal with those escape 
characters. The element produced by the method may or may 
not be empty, and may or may not have attributes.

This program produces the following output:

Demo empty element with attributes.
<ElementName color="Color.RED" width="10" height="20" />

Demo empty element with no attributes.
Probably doesn't make any sense.
<ElementName />

Demo non-empty element with attributes.
<ElementName color="Color.RED" width="10" height="20" >
Content of element.
</ElementName>

Demo non-empty element with no attributes.
<ElementName >
Content of element.
</ElementName>

Tested using J2SE 5.0, Firefox v1.5.0.9, and WinXP.
*********************************************************/
import java.io.*;

public class Svg07{
  public static void main(String argv[]){
    String name = "ElementName";
    System.out.println(
                   "Demo empty element with attributes.");

    String emptyElement = makeElement(true,name,
                         new String[]{"Color","Color.RED",
                                      "width","10",
                                      "height","20"});
    System.out.println(emptyElement);

    System.out.println();
    System.out.println(
                "Demo empty element with no attributes.");
    System.out.println(
                      "Probably doesn't make any sense.");
    emptyElement = makeElement(true,name,null);
    System.out.println(emptyElement);

    System.out.println();
    System.out.println(
               "Demo non-empty element with attributes.");
    String elementStartTag = makeElement(false,name,
                         new String[]{"Color","Color.RED",
                                      "width","10",
                                      "height","20"});
    System.out.println(elementStartTag);
    System.out.println("Content of element.");
    //Create end tag for element
    System.out.println("</" + name + ">");

    System.out.println();
    System.out.println(
            "Demo non-empty element with no attributes.");
    elementStartTag = makeElement(false,name,null);
    System.out.println(elementStartTag);
    System.out.println("Content of element.");
    //Create end tag for element
    System.out.println("</" + name + ">");

  }// end main()
  //----------------------------------------------------//
  /*
  One of the most frustrating things about using Java
   to create elements in XML, XHTML, or HTML is having
   to deal with the escape characters for the many
   required quotation marks. This method constructs an
   element, which may or may not have attributes. Also,
   the element may or may not be empty.
  The user of this method does not have to deal with the
   required quotation marks surrounding attribute values
   and the corresponding escape characters     
  The first incoming parameter must be true if the
   element is empty and false if the element is not
   empty.
  If the first parameter is true, the element is sealed
   off in the required manner for an empty element. If
   the first parameter is false, the method returns the
   complete start tag for the element but does not
   return a complete element. It is the responsibility
   of the calling method to provide the content and the
   end tag for the element.
  The second parameter to the method must be a String
   that specifies the name of the element.
  The third parameter to the method must be a reference
   to an array object of type String.  This array must 
   contain an even number of elements.  Each pair of 
   elements constitutes the name and the value of an 
   attribute, in the order name, value, name, value, etc.

  If the reference to the array object is null and the
   first parameter is false, the method returns the start
   tag for an element that has no attributes and is not 
   empty.
  If the reference is null and the first parameter is
   true, the method returns a complete empty element with 
   no attributes (which probably doesn't make any sense).
   
  An example of the recommended usage of the method
   follows:
   
  String newElement = makeElement(
                         true/false,
                         name,
                         new String[]{"name","value",
                                      "name","value",
                                      "name","value",
                                     });
   
  */
  
  static String makeElement(
          boolean empty,String elementName,String[] data){

    //Begin constructing the start tag.
    String element = "<" + elementName + " ";
    
    //Deal with elements that have no attributes.
    if((empty==false) && (data == null)){
      //Return a complete start tag.
      return element + ">";
    }else if((empty==true) && (data == null)){
      //Return a complete empty element.
      return element + "/>";
    }//end if

    for(int cnt=0;cnt<data.length;cnt+=2){

      String name = data[cnt];
      String value = data[cnt+1];
      element += name + "=" + """ + value + "" ";
    }//end for loop
    
    if(empty){
      //Terminate the element appropriately for an
      // empty element. A complete empty element will
      // be returned.
      element += "/>";
    }else{
      //End the start tag for an element that is not
      // empty. In this case, only the start tag will
      // be returned.  The calling program must provide
      // the content for the element as well as the end
      // tag for the element.
      element += ">";
    }//end else
      
  return element;
  }//end makeElement

}//end Svg07

 

Listing 23. The program named Svg08.

/*File Svg08.java
Copyright 2006 R.G.Baldwin

The purpose of this program is to demonstrate the use of 
a new graphics method that can be used to create a general
node having any name, and any number of attributes with 
any attribute names and any String values for the 
attributes, or no attributes at all.

The program creates a DOM tree describing a specific 
graphic image in SVG format and writes it out into an XML 
file named junk.svg.

The program illustrates three different ways to use the
methods of the SVG graphics library to create ellipses
having different attribute values.

The output file produced by this program can be rendered 
by loading it into Firefox 1.5.

Tested using J2SE 5.0, Firefox v1.5.0.8, and WinXP.
*********************************************************/

import javax.xml.parsers.*;
import org.w3c.dom.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;

public class Svg08 {

  public static void main(String[] args){

    //Begin by creating a DOM tree that represents the XML
    // code that will render to produce the image of
    // interest.

    //Get the Document object.
    Document document = SvgGraphics.getDocument();

    //Create the root node named svg and append it to the
    // document.  Specify the parent as null for the
    // special case where the parent is the document.
    // Otherwise, specify the actual parent node.
    Element svg = SvgGraphics.makeNode(
        document,
        null,//parent
        "svg",//node type
        new String[]{"xmlns","http://www.w3.org/2000/svg",
                     "version","1.1",
                     "width","220",
                     "height","440",
                     "position","absolute",
                     "top","0",
                     "left","0",
                    });//end makeNode method



      //Show outline of canvas using 'rect' element
      Element outline = SvgGraphics.makeNode(document,
                                         svg,//parent
                                         "rect",//type
        new String[]{"x","0",
                     "y","0",
                     "width","220",
                     "height","440",
                     "fill","none",
                     "stroke","black",
                     "stroke-width","1",
                    });//end makeNode method

    //Create a node named g, which will be the parent for
    // an ellipse. Pass null for the reference to the
    // array object for the special case where the node
    // has no attributes.
    Element g = SvgGraphics.makeNode(document,
                                     svg,//parent
                                     "g",
                                     null);
                                     
    //Draw a blue line 12 pixels wide.  First define the
    // line by providing values for the four default
    // attributes of the makeLine method that specify the
    // end point locations of the line.  Then supplement
    // those attributes by invoking the setAttribute
    // method twice in succession on the reference to the
    // line to set the stroke and stroke-width attributes,
    // causing the line to be blue with a width of 12
    // pixels.
    Element line = SvgGraphics.makeLine(document,
                                        g,   //owner
                                        0,   //x1
                                        0,   //y1
                                        220, //x2
                                        440);//y2
    line.setAttribute("stroke","blue");
    line.setAttribute("stroke-width","12");
    

    //Draw a black ellipse by providing values for the
    // four default attributes of the makeEllipse method
    // that specify the location and size of the ellipse.
    // The ellipse is black because the attribute that
    // controls the color was not set.
    SvgGraphics.makeEllipse(document,//This document
                            g,//Owner
                            110,//Center x-coordinate
                            100,//Center y-coordinate
                            100,//Width
                            40); //Height

    //Draw an ellipse by providing values for the four
    // default attributes of the makeEllipse method that
    // specify the location and size of the ellipse. Then
    // supplement those attributes by invoking the
    // setAttribute method on the reference to the ellipse
    // twice to fill the ellipse with red color and to
    // cause the filled ellipse to have 60% opacity.
    Element ellipse2 = SvgGraphics.makeEllipse(
                           document,
                           g,//Owner
                           110,//Center x-coordinate
                           200,//Center y-coordinate
                           100,//Width
                           40); //Height
    ellipse2.setAttribute("style","fill:red");
    ellipse2.setAttribute("opacity","0.6");
    
    //Draw a green ellipse with 60% opacity rotated by
    // 15-degrees clockwise, using the makeNode method,
    // for which there are no default attributes.
    //This method lets you set all, none, or any
    // combination of attribute values in order to
    // take advantage of none, any, or all of the
    // available attributes with no assumptions being
    // made about any of the attributes. This is the
    // most general of the three approaches.
    
    Element ellipse3 = SvgGraphics.makeNode(
      document,
      g,//parent
      "ellipse",//node type
      new String[]{"cx","110",
                   "cy","300",
                   "rx","100",
                   "ry","40",
                   "style","fill:green",
                   "opacity","0.6",
                   "transform","translate(110,300) "
                             + "rotate(15) "
                             + "translate(-110,-300)"
                  });//end makeNode method  
    
    //Transform the DOM and write the output file.
    SvgGraphics.transformTheDom(document,"junk.svg");

  }// end main()
  //----------------------------------------------------//
  
}// class Svg08
//======================================================//

//This is an abbreviated library used solely to support 
// this program for the purpose of demonstrating the
// method named makeNode.
class SvgGraphics{
  //----------------------------------------------------//
  
  /*
  The purpose of this method is to create a general node
   having any name, and any number of attributes with any 
   attribute names and any String values for the 
   attributes, or no attributes at all.
   
  The first parameter is a reference to the document to
   which the new node belongs.
  
  The second parameter is a reference to the parent node
   to which this node is to be appended so as to become a
   child of that node. If this parameter is null, the new
   node is appended to the document.  Otherwise, it is
   appended to the specified parent node.
   
  The third parameter is a String that specifies the type
   of node.
  
  The fourth parameter to the method must be a reference
   to an array object of type String.  This array must 
   contain an even number of elements.  Each pair of 
   elements constitutes the name and the value of an 
   attribute, in the order name, value, name, value, etc.
  
  An example of the recommended usage of the method
   follows:
    Element abc = SvgGraphics.makeNode(
                      document,
                      def,//parent could be null
                      "ghi",//node type
                      new String[]{"name","value",
                                   "name","value",
                                   "name","value",
                                  });//end makeNode method
  */
  static Element makeNode(Document document,
                                Element parent,
                                String nodeType,
                                String[] data){
  
    Element element = 
                (Element)document.createElement(nodeType);
    
    if(parent == null){
      //For the special case of parent equal to null,
      // append the new node to the document.
      document.appendChild(element);
    }else{
      //Otherwise, append the new node to the specified
      // parent.
      parent.appendChild(element);
    }//end else
  
    //Deal with elements that have no attributes.
    if(data == null){
      return element;
    }//end if
    
    for(int cnt=0;cnt<data.length;cnt+=2){
      String name = data[cnt];
      String value = data[cnt+1];
      element.setAttribute(name,value);
    }//end for loop
    
    return element;
  }//end makeNode
  //----------------------------------------------------//

  //This method returns a reference to an ellipse. The
  // xCoor and yCoor parameters specify the center of the
  // ellipse.  The xRadius and yRadius parameters specify
  // the width and height of the  ellipse respectively
  // while it is in the horizontal plane before being
  // rotated.  Numeric attributes are set at type String.
  static Element makeEllipse(Document document,
                             Element parent,
                             int xCoor,
                             int yCoor,
                             int xRadius,
                             int yRadius){
    Element ellipse  = 
               (Element)document.createElement("ellipse");
    parent.appendChild(ellipse);
    ellipse.setAttribute("cx",""+xCoor);
    ellipse.setAttribute("cy",""+yCoor);
    ellipse.setAttribute("rx",""+xRadius);
    ellipse.setAttribute("ry",""+yRadius);
    return ellipse;
  }//end makeEllipse
  //----------------------------------------------------//

  //This is a utility method that is used to execute code
  // that is the same regardless of the graphic image
  // being produced. This method is not new to this
  // program.
  static Document getDocument(){
    Document document = null;
    try{
      DocumentBuilderFactory factory = 
                     DocumentBuilderFactory.newInstance();

      DocumentBuilder builder = 
                             factory.newDocumentBuilder();
      document = builder.newDocument();
      document.setXmlStandalone(false);
    }catch(Exception e){
      e.printStackTrace(System.err);
      System.exit(0);
    }//end catch
    return document;
  }//end getDocument
  //----------------------------------------------------//
  
  //This is a utility method that is used to execute code
  // that is the same regardless of the graphic image
  // being produced.  This method transforms the DOM into
  // raw XML code and writes that code into the output
  // file. This method is not new to this program.
  static void transformTheDom(Document document,
                              String filename){
    try{
      //Get a TransformerFactory object.
      TransformerFactory xformFactory =
                         TransformerFactory.newInstance();
           
      //Get an XSL Transformer object.
      Transformer transformer = 
                            xformFactory.newTransformer();
      
      //Sets the standalone property in the first line of
      // the output file.
      transformer.setOutputProperty(
                              OutputKeys.STANDALONE,"no");
      
      //Get a DOMSource object that represents the
      // Document object
      DOMSource source = new DOMSource(document);


      //Get an output stream for the output file.
      PrintWriter outStream = new PrintWriter(filename);

      //Get a StreamResult object that points to the
      // output file.  Then transform the DOM sending XML
      // code to the file
      StreamResult fileResult = 
                              new StreamResult(outStream);
      transformer.transform(source,fileResult);
    }//end try block

    catch(Exception e){
      e.printStackTrace(System.err);
    }//end catch
  }//end transformTheDom
  //----------------------------------------------------//
  
  //This method returns a reference to a line. x1 and y1
  // specify the starting point of the line before it is
  // rotated. x2 and y2 specify the end point.  By
  // default, the stroke is set to black one pixel wide.
  // This can be overridden to specify other colors and
  // other widths if you need to do so.
  static Element makeLine(Document document,
                          Element parent,
                          int x1,
                          int y1,
                          int x2,
                          int y2){
    Element line  = 
                  (Element)document.createElement("line");
    parent.appendChild(line);
    line.setAttribute("x1",""+x1);
    line.setAttribute("y1",""+y1);
    line.setAttribute("x2",""+x2);
    line.setAttribute("y2",""+y2);
    line.setAttribute("stroke","black");
    line.setAttribute("stroke-width","1");
    return line;
  }//end makeLine
  //----------------------------------------------------//
  
}//end class SvgGraphics


Copyright

Copyright 2007, Richard G. Baldwin.  Reproduction in whole or in part in any
form or medium without express written permission from Richard Baldwin is
prohibited.

Resources

Java 2D Graphics
300 Java 2D Graphics,
Nested Top-Level Classes and Interfaces 
302 Java 2D Graphics,
The Point2D Class 
304 Java 2D Graphics,
The Graphics2D Class 
306 Java 2D Graphics,
Simple Affine Transforms 
308 Java 2D Graphics,
The Shape Interface, Part 1 
310 Java 2D Graphics,
The Shape Interface, Part 2 
312 Java 2D Graphics,
Solid Color Fill 
314 Java 2D Graphics,
Gradient Color Fill 
316 Java 2D Graphics,
Texture Fill 
318 Java 2D Graphics,
The Stroke Interface 
320 Java 2D Graphics,
The Composite Interface and Transparency 
322 Java 2D Graphics,
The Composite Interface, GradientPaint, and Transparency 
324 Java 2D Graphics,
The Color Constructors and Transparency
Java 2D API
Specification

Java 2D API

Java API for XML Processing (JAXP)
2200 Java
API for XML Processing (JAXP), Getting Started
2202 Getting
Started with Java JAXP and XSL Transformations (XSLT)
2204 Java
JAXP, Exposing a DOM Tree
2206 Java
JAXP, Implementing Default XSLT Behavior in Java
2208 Java
JAXP, Writing Java Code to Emulate an XSLT Transformation
2210 Java
JAXP, Transforming XML to XHTML
Links to numerous XML tutorials
by Richard G. Baldwin

Scalable Vector Graphics (SVG)
Java JAXP, Creating graphics using Java and SVG
Scalable Vector Graphics (SVG) 1.1
Specification

Adobe SVG Viewer plug-in

Create vector graphics in the browser with SVG
by Uche Ogbuji
SVG Tutorial
SVG Basics

About the author

Richard Baldwin is a
college professor (at Austin Community College in Austin, TX) and private
consultant whose primary focus is a combination of Java, C#, and XML. In
addition to the many platform and/or language independent benefits of Java and
C# applications, he believes that a combination of Java, C#, and XML will become
the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects and he
frequently provides onsite training at the high-tech companies located in and
around Austin, Texas.  He is the author of Baldwin’s Programming
Tutorials, which have gained a
worldwide following among experienced and aspiring programmers. He has also
published articles in JavaPro magazine.

In addition to his programming expertise, Richard has many years of
practical experience in Digital Signal Processing (DSP).  His first job after he
earned his Bachelor’s degree was doing DSP in the Seismic Research Department of
Texas Instruments.  (TI is still a world leader in DSP.)  In the following
years, he applied his programming and DSP expertise to other interesting areas
including sonar and underwater acoustics.

Richard holds an MSEE degree from Southern Methodist University and has
many years of experience in the application of computer technology to real-world
problems.

Baldwin@DickBaldwin.com

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories