- Inherits from:
- NSObject
- Package:
- com.apple.webobjects.xml
Use this class to construct ("decode") an object from XML data. Decoding can take place either with or without a mapping model. The mapping model provides greater control over the decoding process and is typically used when you are encoding and decoding XML that is destined for, or originates from, an external source. When the WOXMLCoder and WOXMLDecoder are used as an archiving mechanism, the mapping model is usually not necessary. For more information on the mapping model, see the "The Format of the Mapping Model" in the framework introduction.
On its own, without a mapping model, WOXMLDecoder is able to decode any object as long as the object and all of its children either implement the WOXMLCoding interface or are an instance of String, Number (or a subclass, provided that the subclass doesn't add instance variables), NSArray, NSDictionary, NSDate, NSData, or EOEnterpriseObject (or a subclass, providing that all instance variables are either attributes or relationships). To construct an object from XML data, invoke one of the decodeRootObject methods.
Objects that implement the WOXMLCoding interface must also implement a single-argument constructor that takes a WOXMLDecoder object as the single argument if they are to be decoded. Within this constructor you decode your object's instance variables using WOXMLDecoder's various decode...ForKey methods.
The following simple "Person" class implements both the single-argument constructor needed to decode objects of this class and the WOXMLCoding interface.
import com.apple.webobjects.xml.*; import com.apple.yellow.foundation.*; import java.lang.*; import java.net.*; import java.math.*; public class Person extends Object implements WOXMLCoding { String name; boolean married; int children; public Person() { name = "John Smith"; married = true; children = 2; } public void encodeWithWOXMLCoder(WOXMLCoder coder) { coder.encodeObjectForKey(name, "Name"); coder.encodeBooleanForKey(married, "MaritalStatus"); coder.encodeIntForKey(children, "NumberOfChildren"); } // constructor required for decoding public Person(WOXMLDecoder decoder) { name = (String)decoder.decodeObjectForKey("Name"); married = decoder.decodeBooleanForKey("MaritalStatus"); children = decoder.decodeIntForKey("NumberOfChildren"); } }
See the XMLArchiving example (accessible through the WebObjects Info Center under Examples > WebObjects > Java > XMLArchiving) for a more complete example.
The mapping decoder gives you much greater control over the decoding process, since it operates under the direction of an XML-format mapping model that you create. This mapping model allows you to specify how XML elements and attributes are to be mapped to objects and object attributes (the mapping is performed using key-value coding). Because of the added power and flexibility the mapping model provides, the mapping decoder is particularly well-suited to decode XML that wasn't generated by the WOXMLCoder.
Suppose you had the following XML:
<command quantity="10"> <customer><name>Ringle</name></customer> <fullMovie name="Alien"> <date>1979-10-25 00:00:00 -0700</date> <cat>Horror</cat> <role name="Brett"></role> <role name="Kane"></role> <role name="Dallas"></role> <role name="Parker"></role> <role name="Lambert"></role> <role name="Ash"></role> <role name="Ripley"></role> </fullMovie> </command>
Futher suppose that you wanted to decode the above XML into an object of the following class:
public class Command extends NSObject { public EOGenericRecord movie; public NSMutableDictionary customer; public int qty; }
The WOXMLDecoder will do the job for you given the following mapping model:
<model> <entity name="Command" xmlTag="command"> <property name="qty" xmlTag="quantity" attribute="YES"/> <property name="movie" xmlTag="movie"/> <property name="customer" xmlTag="customer"/> </entity> <entity name="MyMovie" xmlTag="movie"> <property name="title" xmlTag="name" attribute="YES"/> <property name="dateReleased" xmlTag="date"> <property name="roles" xmlTag="role"> <property name="category" xmlTag="cat"/> </entity> <entity name="com.apple.yellow.eocontrol.EOGenericRecord" xmlTag="role"> <property name="roleName" xmlTag="name" attribute="YES"/> </entity> </model>
The above is a simple example; see the RelatedLinks example (accessible through the WebObjects Info Center under Examples > WebObjects > Java > RelatedLinks) for a more complete example illustrating the use of the WOXMLDecoder with a mapping model.
- Creating a WOXMLDecoder
- decoder
- decoderWithMapping
- Decoding XML
- decodeRootObject
- Reconstructing an object's contents without a mapping model
- decodeBooleanForKey
- decodeDoubleForKey
- decodeFloatForKey
- decodeIntForKey
- decodeObjectForKey
- Working with the XML parser
- parser
- parserClassName
- setParserClassName
public static WOXMLDecoder decoder()
Creates and returns a new WOXMLDecoder object.
public static WOXMLDecoder decoderWithMapping(String mappingURL)
Creates and returns a new WOXMLDecoder object that decodes XML based upon the mapping model specified by mappingURL. For more information, see "Decoding XML With a Mapping Model" .
Windows NT uses backslashes
where other systems use forward slashes. When prepending the "file:"
URL prefix to a path such as is returned by WOResourceManager's pathForResourceNamed method,
on Windows NT the prefix must be "file:\\" while on all other platforms
the prefix must be "file://". See the RelatedLinks example for
one way to select the proper prefix based upon the underlying system. |
public boolean decodeBooleanForKey(String key)
Invoke this method from within in your single-argument constructor to set a boolean instance variable to the value of the key element within the XML being decoded. For example, to extract the marital status from the following XML:
<element type="Person" objectID="4"> <Name type="java.lang.String" objectID="5">John Smith</Name> <MaritalStatus type="boolean">True</MaritalStatus> <NumberOfChildren type="int">2</NumberOfChildren> </element>
You could use something similar to the following:
married = decoder.decodeBooleanForKey("MaritalStatus");
public double decodeDoubleForKey(String key)
Invoke this method from within in your single-argument constructor to set an instance variable of type double to the value of the key element within the XML being decoded.
See Also: decodeIntForKey
public float decodeFloatForKey(String key)
Invoke this method from within in your single-argument constructor to set an instance variable of type int to the value of the key element within the XML being decoded.
See Also: decodeIntForKey
public int decodeIntForKey(String key)
Invoke this method from within in your single-argument constructor to set an instance variable of type int to the value of the key element within the XML being decoded. For example, to extract the number of children from the following XML:
<element type="Person" objectID="4"> <Name type="java.lang.String" objectID="5">John Smith</Name> <MaritalStatus type="boolean">True</MaritalStatus> <NumberOfChildren type="int">2</NumberOfChildren> </element>
You could use something similar to the following:
children = decoder.decodeIntForKey("NumberOfChildren");
public Object decodeObjectForKey(String key)
Invoke this method from within in your single-argument constructor to set an instance variable to a newly constructed object whose class and content depends upon the value of the key element within the XML being decoded. The object being decoded must meet the same criteria outlined in decodeRootObject; if not, or if an error arises during the construction of the object, decodeObjectForKey throws a WOXMLException.
public synchronized Object decodeRootObject(NSData data)
public synchronized Object decodeRootObject(String XMLfileURL)
public synchronized Object decodeRootObject(
org.xml.sax.InputSource inputSource)
Decodes the indicated XML and constructs a corresponding object. decodeRootObject accepts XML either in an NSData object, in a file, or through an InputSource. If the XML resides within a file, XMLfileURL should be a URL that identifies the file containing the XML. If the XML resides within a String object, use a StringReader object to supply an InputSource, like this:
stringReader = new StringReader(xmlString); is = new InputSource(stringReader); // invoke setEncoding (on the input source) if the XML contains multibyte characters decodedObject = (NSMutableArray)myDecoder.decodeRootObject(is);
In
the above example, xmlString
is
a String object that contains the XML for an encoded NSMutableArray
object.
Each object encoded within the XML must have a type attribute that indicates the object's class. Each encoded object must be one of the following:
Objects that implement the WOXMLCoding interface must also implement a special constructor; see "Decoding XML Without a Mapping Model" for more information and an example.
If the parser is unable to parse the supplied XML, decodeRootObject throws a WOXMLException that encloses either a SAXException or an IOException.
public org.xml.sax.Parser parser()
Returns the XML parser (instantiating one based upon the parser class name, if necessary). This method throws a ClassNotFoundException if the parser class cannot be located, and an InstantiationException or IllegalAccessException if the parser cannot be created. The default parser is the SAX parser (com.ibm.xml.parsers.SAXParser).
This method is invoked by decodeRootObject.
See Also: parserClassName, setParserClassName
public String parserClassName()
Returns the name of the XML parser's class. By default, this is "com.ibm.xml.parsers.SAXParser".
See Also: parser, setParserClassName
public void setParserClassName(String className)
See Also: parser, parserClassName