Need to save properties in XML file

A

alexkuzn

I need to save spreadsheet properties(spreadsheet name, column name,
column width etc.) in XML file.
Can anyone give me any tips? I am not very familiar with XML so any
advise is very appreciated.
I am using 1.5 JDK

Thanks!
 
A

Alex

What do I need to do if one of the members of my class I need to store
in xml is a List object
I do have setMyList(), getMyList() but List is not saved in XML.

Thanks
 
R

Roedy Green

I need to save spreadsheet properties(spreadsheet name, column name,
column width etc.) in XML file.
Can anyone give me any tips? I am not very familiar with XML so any
advise is very appreciated.

Who is going to read the XML file? Somebody has to sit down and decide
what the tags are going to be.

Then it becomes just matter of enclosing the fields in giant great
<tag></tag> markers that are bigger than the fields.

You also have the matter of &lt; and &gt; entities to deal with
accidental use of < and >.

Writing is quite a bit easier than reading. See
http://mindprod.com/jgloss/xml.html
 
R

Roedy Green

I do have setMyList(), getMyList() but List is not saved in XML.

you save it in XML. You might do something like
<list><item>first</item><item>second</item></list>


If all you are trying to do is allow multivalued properties, this
class might do for you:

package com.mindprod.replicatorcommon;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.regex.Pattern;

import com.mindprod.replicatorsender.ReplicatorSender;

/**
* This class is similar to java.util.Properties. The properties file
has a
* similar key=value format. However, for MultiProperties, spaces in
the values
* are not coded as "\ ", just as plain " ". Values can be a tuple
separated by
* commas. The inherited Hashtable get returns a String[]. There is no
support
* for extended chars such as \n. There is no support for \ as a
continuation
* character. Comment lines begin with #. Blank lines are ignored. The
file must
* end with a line separator. All values are trimmed of leading and
trailing
* spaces. All Strings are interned, so they behave just like
hard-coded String
* static finals. It is basically just a Hashtable with a load method
and a few
* conveniences added to the get method.
*
* @author Roedy Green
* @version 1.0
* @since 2003-08-03
*/
public class MultiProperties extends Hashtable<String, String[]> {

/**
* true if you want the debugging harness, this is NOT the
DEBUGGING
* property.
*/
private static final boolean DEBUGGING = false;

/**
* A dummy empty array of Strings. No point is allocating a fresh
one every
* time it is needed.
*/
private static String[] dummy = new String[ 0 ];

// Pattern to split line into key and value at the =
private static Pattern keyValueSplitter = Pattern.compile( "=" );

/**
* Pattern to split into words separated by commas. Two commas in
a row in
* the String to be matched gives an empty field
*/
private static Pattern subFieldSplitter = Pattern.compile( "," );

/**
* Get value associated with key.
*
* @param key
* Key, case sensitive.
* @param defaultValue
* Value for the default if the key is not defined.
key=nothing
* returns "", not the default value.
* @return String for a single value, or the first of a set of
multiple
* values, or "".
*/
public String get ( String key, String defaultValue )
{
Object value = get( key );
if ( value == null )
{
return defaultValue.intern();
}
else
{
String[] array = ( (String[])value );
if ( array.length != 0 )
{
return array[ 0 ];
}
else
{
return ""; // not defaultValue!
}
}
}

/**
* Get boolean value associated with key. Valid values for key are
true,
* false, yes, no, case insensitive.
*
* @param key
* Key, case sensitive.
* @param defaultValue
* Value for the default if the key is not defined.
* @return boolean value of the key, or defaultValue if not
defined or if
* key=
*/
public boolean getBoolean ( String key, boolean defaultValue )
{
Object value = get( key );
if ( value == null )
{
return defaultValue;
}
else
{
String[] array = ( (String[])value );
if ( array.length != 0 )
{
return array[ 0 ].equalsIgnoreCase( "true" )
|| array[ 0 ].equalsIgnoreCase( "yes" );
}
else
{
return defaultValue;
}
}

}

/**
* Get single integer value associated with key.
*
* @param key
* Key, case sensitive.
* @param defaultValue
* Value for the default if the key is not defined.
* @return integer value of the key, or defaultValue if not
defined or if
* key=
* @exception NumberFormatException
* if the value is not a valid integer.
*/
public int getInt ( String key, int defaultValue )
throws NumberFormatException
{
Object value = get( key );
if ( value == null )
{
return defaultValue;
}
else
{
String[] array = ( (String[])value );
if ( array.length != 0 )
{
return Integer.parseInt( array[ 0 ] );
}
else
{
return defaultValue;
}
}

}

/**
* Get values associated with key.
*
* @param key
* Key, case sensitive.
* @return array of associated Strings, possibly dimension 0. If
key is
* undefined returns empty array, not null.
*/
public String[] getMultiple ( String key )
{
String[] value = (String[])get( key );
if ( value == null )
{
return dummy;
}
else
{
return value;
}
}

/**
* Load the properties hashtable from a text file of key=value
pairs.
*
* @param in
* where to load the textual key=value pairs from.
* @exception IOException
*/
public void load ( InputStream in ) throws IOException
{
BufferedReader br = new BufferedReader( new InputStreamReader(
in ) );

while ( true )
{
String line = br.readLine();
if ( line == null )
{
/* eof */
break;
}
if ( line.startsWith( "#" ) )
{
/* ignore comments */
continue;
}
line = line.trim();
if ( line.length() == 0 )
{
/* ignore blank lines */
continue;
}

// split line into key and value
String[] keyValue = keyValueSplitter.split( line );
switch ( keyValue.length )
{
case 1 :
{
// key=nothing
String key = keyValue[ 0 ].trim().intern();
if ( key.length() == 0 )
{
complain( line );
}
this.put( key, dummy );
}
break;

case 2 :
{
// key=value
String key = keyValue[ 0 ].trim().intern();
if ( key.length() == 0 )
{
complain( line );
}
// Split value into subfields
String[] values = subFieldSplitter.split( keyValue[ 1
].trim() );

// trim the multiple values
for ( int i = 0; i < values.length; i++ )
{
values[ i ] = values[ i ].trim().intern();
}
// save in the underlying Hashtable.
this.put( key, values );
}
break;

default :
case 0 :
complain( line );
}
} // end while
br.close();
} // end load

/**
* Constructs a new, empty hashtable with the specified initial
capacity and
* the specified load factor. See
http://mindprod.com/jgloss/hashtable.html
* for a full description of what the initialCapacity and
loadFactors mean.
*
* @param initialCapacity
* the initial capacity of the hashtable.
* @param loadFactor
* the load factor of the hashtable.
* @exception IllegalArgumentException
* if the initial capacity is less than zero, or if the
load
* factor is nonpositive.
*/
public MultiProperties( int initialCapacity, float loadFactor )
{
super( initialCapacity, loadFactor );
}

/**
* Complain about malformed data.
*
* @param line
* Line of key=value that has a problem.
*/
private static void complain ( String line )
{
throw new IllegalArgumentException(
"MultiProperties: malformed key=value : " + line );
}

/**
* test harness
*
* @param args
* not used
*/
public static void main ( String[] args )
{
if ( DEBUGGING )
{
MultiProperties m = new MultiProperties( 100, .75f );
try
{
m.load( new FileInputStream( "replicator.properties" )
);
}
catch ( IOException e )
{
ReplicatorSender
.fatal( "Unable to read replicator.properties
file."
+ "\n"
+ e.getMessage() );
}
for ( Enumeration e = m.keys(); e.hasMoreElements(); )
{
String key = (String)e.nextElement();
String[] values = m.getMultiple( key );
System.out.println( key + " =" );
for ( int i = 0; i < values.length; i++ )
{
System.out.println( values[ i ] );
}
} // end for
} // end if DEBUGGING
} // end main
} // end MultiProperties
 
T

Thomas Hawtin

Roedy said:
You also have the matter of &lt; and &gt; entities to deal with
accidental use of < and >.

Escaping & is quite useful as well. Probably non-XML characters should
be dealt with too.

Not escaping the escape character seems a common mistake. I've seen code
committed that forgot to escape & for XML. Also code in production that
didn't escape \ in SQL. The maintenance guy assigned to that one took
some persuading that it was a problem.

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top