Ayhan Ulusoy > XML-Pastor-1.0.4 > XML::Pastor::Type

Download:
XML-Pastor-1.0.4.tar.gz

Dependencies

Annotate this POD

CPAN RT

New  2
Open  0
View/Report Bugs
Source  

NAME ^

XML::Pastor::Type - Ancestor of XML::Pastor::ComplexType and XML::Pastor::SimpleType.

WARNING ^

This module is used internally by XML::Pastor. You do not normally know much about this module to actually use XML::Pastor. It is documented here for completeness and for XML::Pastor developers. Do not count on the interface of this module. It may change in any of the subsequent releases. You have been warned.

ISA ^

This class descends from Class::Data::Inheritable.

DESCRIPTION ^

XML::Pastor::Type is an abstract ancestor of XML::Pastor::ComplexType and XML::Pastor::SimpleType and therefore indirectly of all simple and complex classes generated by XML::Pastor which is a Perl code generator from W3C XSD schemas. For an introduction, please refer to the documentation of XML::Pastor.

XML::Pastor::SimpleType defines a class data accessor called "XmlSchemaType()" with the help of Class::Data::Inheritable. This accessor is normally used by many other methods to access the W3C schema meta information related to the class at hand. But at this stage, "XmlSchemaType()" does not contain any information.

The generated subclasses set "XmlSchemaType()" to information specific to the W3C schema type. It is then used for the XML binding and validation methods.

METHODS ^

CONSTRUCTORS

new()

  $class->new(%fields)

CONSTRUCTOR.

The new() constructor method instantiates a new XML::Pastor::Type object. It is inheritable, and indeed inherited, by the generated decsendant classes. Normally, you do not call the new method on XML::Pastor::Type. You rather call it on your generated subclasses.

Any -named- fields that are passed as parameters are initialized to those values within the newly created object.

  my $object = $class->new();

Any -named- fields that are passed as parameters are initialized to those values within the newly created object.

  my $object = $class->new(code=>'fr', name='France');

Notice that you can pass any field name that can be used as a hash reference. It doesn't have to be a valid XML attribute or child element. You may then access the same field using the usual hash access. You can use this feature to save state information that will not be written back to XML. Just make sure that the names of any such fields do not coincide with the name of actual an attribute or child element. Any such field will be silently ignored when writing to or validating XML. However, note that there won't be any auto-generated accessor for such fields. But you can actually achieve this by using the mk_accessor method from Class::Accessor somewhere else in your code as XML::ComplexType eventually inherits from Class::Accessor.

.

from_xml()

  $object = $class->from_xml($resource);

CONSTRUCTOR that should be called upon your generated class rather than XML::Pastor::ComplexType.

The from_xml method is a generic method that enables to instantiate a class from a variety of XML resources (DOM, URL, file, file handle, string). The actual method that will be called will be determined by looking at the '$resource' parameter.

If '$resource' is an object (isa) of type XML::LibXML::Document or XML::LibXML::Element, then "from_xml_dom" is called.

  $object = $class->from_xml($dom);

If '$resource' is an object (isa) of type IO::Handle, then "from_xml_fh" is called.

  $object = $class->from_xml($fh);

If '$resource' is an object (isa) of type URI, then "from_xml_url" is called.

  $object = $class->from_xml(URI->new('http://www.example.com/country.xml'));

If '$resource' stringifies to something that looks like a URL (currently http, https, ftp, or file), then "from_xml_url" is called.

  $object = $class->from_xml('ftp://ftp.example.com/country.xml');

If '$resource' stringifies to something that looks like an XML string, then "from_xml_string" is called.

  # Assuming there is a generated class called 'MyApp::Data::country'
  $country = MyApp::Data::country->from_xml(<<'EOF');
  
  <?xml version="1.0"?>
  <country code="FR" name="France">
    <city code="PAR" name="Paris"/>
    <city code="LYO" name="Lyon"/>    
  </country>
  EOF

Otherwise, '$resource' is assumed to be a file name and subsequently "from_xml_file" is called.

  $object = $class->from_xml('/tmp/country.xml');

.

from_xml_dom()

  $object = $class->from_xml_dom($dom);

CONSTRUCTOR that should be called upon your generated class rather than XML::Pastor::ComplexType.

This method instatiates an object of the generated class from a DOM object passed as a parameter. Currently, the DOM object must be either of type XML::LibXML::Document or of type XML::LibXML::Element.

Currently, the method is quite forgiving as to the actual contents of the DOM. Attributes and child elements that fit the original W3C schema defined names will be imported as fields of the newly created object. Those that don't fit the schema will silently be ignored. So there are very few circumstances that this method will die or return 'undef'. Most usually, at worst the object returned will be completely empty (if the XML DOM had nothing to do with the W3C schema definition) but will still be correctly typed.

.

from_xml_fh()

  $object = $class->from_xml_fh($fh);

CONSTRUCTOR that should be called upon your generated class rather than XML::Pastor::ComplexType.

This method instatiates an object of the generated class from an XML string parsed from a file handle passed as an argument.

The contents of the file handle will be parsed using the parse_fh method of XML::LibXML. If the parser dies, this method will also die. The DOM that is obtained from the parser will be passed to "from_xml_dom" for further processing.

Currently, the method is quite forgiving as to the actual contents of the DOM. See "from_xml_dom" for more information on this.

.

from_xml_file()

  $object = $class->from_xml_file($fileName);

CONSTRUCTOR that should be called upon your generated class rather than XML::Pastor::ComplexType.

This method instatiates an object of the generated class from an XML string parsed from a file whose name passed as an argument.

The contents of the file handle will be parsed using the parse_file method of XML::LibXML. If the parser dies, this method will also die. The DOM that is obtained from the parser will be passed to "from_xml_dom" for further processing.

Currently, the method is quite forgiving as to the actual contents of the DOM. See "from_xml_dom" for more information on this.

.

from_xml_fragment()

  $object = $class->from_xml_fragment($fragment);

CONSTRUCTOR that should be called upon your generated class rather than XML::Pastor::ComplexType.

This method instatiates an object of the generated class from an XML fragment passed as an argument.

  # Assuming there is a generated class called 'MyApp::Data::country'
  $country = MyApp::Data::country->from_xml_fragment(<<'EOF');
  
  <country code="FR" name="France">
    <city code="PAR" name="Paris"/>
    <city code="LYO" name="Lyon"/>    
  </country>
  EOF

The difference between an XML fragment and an XML string is that in XML fragment the ?xml version="1.0"? is missing. This method will prepend this to the scalar that is passed as an argument and then simply call "from_xml_string".

Currently, the method is quite forgiving as to the actual contents of the DOM. See "from_xml_dom" for more information on this.

.

from_xml_string()

  $object = $class->from_xml_string($scalar);

CONSTRUCTOR that should be called upon your generated class rather than XML::Pastor::ComplexType.

This method instatiates an object of the generated class from an XML string passed as an argument.

  # Assuming there is a generated class called 'MyApp::Data::country'
  $country = MyApp::Data::country->from_xml_string(<<'EOF');

  <?xml version="1.0"?>  
  <country code="FR" name="France">
    <city code="PAR" name="Paris"/>
    <city code="LYO" name="Lyon"/>    
  </country>
  EOF

The contents of the string will be parsed using the parse_string method of XML::LibXML. If the parser dies, this method will also die. The DOM that is obtained from the parser will be passed to "from_xml_dom" for further processing.

Currently, the method is quite forgiving as to the actual contents of the DOM. See "from_xml_dom" for more information on this.

.

from_xml_url()

  $object = $class->from_xml_url($url);

CONSTRUCTOR that should be called upon your generated class rather than XML::Pastor::ComplexType.

This method instatiates an object of the generated class from an XML document that can be retrieved with the GET method from the URL passed as an argument. The URL can be a scalar or a URI object.

This method will first slurp the contents of the URL using the GET method via LWP::UserAgent. If the retrieval did not go well, the method will die.

Then, the content so retrieved will be parsed using the parse_string method of XML::LibXML. If the parser dies, this method will also die. The DOM that is obtained from the parser will be passed to "from_xml_dom" for further processing.

Currently, the method is quite forgiving as to the actual contents of the DOM. See "from_xml_dom" for more information on this.

.

XML STORAGE METHODS

to_xml()

  $object->to_xml($resource, %options);

OBJECT METHOD that may be called upon objects of your generated complex classes.

The to_xml method is a generic method that enables to store an object in XML to a variety of XML resources (DOM, URL, file, file handle, string). The actual method that will be called will be determined by looking at the '$resource' parameter.

Currently, %options may contain a field called name which is necessary only when the class corresponds to a complex type definition in the schema. When it corresponds to a global element, the name of the element is already known, but in other cases this information must be supplied. In fact, Pastor carries out a last ditch effort to recover the name of the element if it has been previously been parsed from DOM, but don't count on this. The rule of the thumb is, if your class corresponds to a global element, you do NOT have to provide a name for the element to be written. Otherwise, you do have to provide it.

If '$resource' is an object (isa) of type IO::Handle, then "to_xml_fh" is called.

  $object->to_xml($fh);

or, if the object is not a class that corresponds to a global element,

  $object->to_xml($fh, name=>country);  # asssuming you would like to save this complex object as the element 'country'

If '$resource' is an object (isa) of type URI, then "to_xml_url" is called.

  $object->to_xml(URI->new('http://www.example.com/country.xml'));

If '$resource' stringifies to something that looks like a URL (currently http, https, ftp, or file), then "to_xml_url" is called.

  $object ->to_xml('ftp://ftp.example.com/country.xml');

If '$resource' is a scalar reference or undef, then "to_xml_string" is called and the result is returned.

  $output = $object->to_xml();

Otherwise, '$resource' is assumed to be a file name and subsequently "to_xml_file" is called.

  $object->to_xml('/tmp/country.xml');

The only option supported at this time is 'encoding' which is 'UTF-8' by default.

  $object->to_xml('/tmp/country.xml',  encoding  => 'iso-8859-1');

.

to_xml_dom()

  $object->to_xml_dom(%options);

OBJECT METHOD that may be called upon objects of your generated complex classes.

This method stores the XML contents of a generated complex class in a LibXML DOM node and returns the resulting node (element).

Currently, %options may contain a field called name which is necessary only when the class corresponds to a complex type definition in the schema. When it corresponds to a global element, the name of the element is already known, but in other cases this information must be supplied. In fact, Pastor carries out a last ditch effort to recover the name of the element if it has been previously been parsed from DOM, but don't count on this. The rule of the thumb is, if your class corresponds to a global element, you do NOT have to provide a name for the element to be written. Otherwise, you do have to provide it.

For a class corresponding to a global element:

        $dom = $object->to_xml_dom();

or, for a class corresponding to complex type definition:

        $dom = $object->to_xml_dom(name=>'country'); # Assuming you want your element to be called 'country'.

No validation occurs proir to storage. If you want that, please do it yourself beforehand using "xml_validate" or "is_xml_valid".

The only option supported at this time is 'encoding' which is 'UTF-8' by default.

  $object->to_xm_dom(encoding  => 'iso-8859-1');

.

to_xml_dom_document()

  $object->to_xml_dom_document(%options);

OBJECT METHOD that may be called upon objects of your generated complex classes.

This method stores the XML contents of a generated complex class in a LibXML DOM node and returns the owner document node of type XML::LibXML::Document.

For the %options please see "to_xml_dom".

For a class corresponding to a global element:

        $dom_doc = $object->to_xml_dom_document();

or, for a class corresponding to complex type definition:

        $dom_doc = $object->to_xml_dom_document(name=>'country'); # Assuming you want your ROOT element to be called 'country'.

No validation occurs proir to storage. If you want that, please do it yourself beforehand using "xml_validate" or "is_xml_valid".

The only option supported at this time is 'encoding' which is 'UTF-8' by default.

  $object->to_xm_dom_document(encoding  => 'iso-8859-1');

.

to_xml_fh()

  $object->to_xml_fh($fh, %options);

OBJECT METHOD that may be called upon objects of your generated complex classes.

This method writes the XML contents of a generated complex class in a file handle (IO::Handle) passed as the first argument '$fh'.

For the %options please see "to_xml_dom".

For a class corresponding to a global element:

        $object->to_xml_fh($fh);

or, for a class corresponding to complex type definition:

        $object->to_xml_fh($fh, name=>'country'); # Assuming you want your ROOT element to be called 'country'.

No validation occurs proir to storage. If you want that, please do it yourself beforehand using "xml_validate" or "is_xml_valid".

The 'encoding' option is 'UTF-8' by default.

.

to_xml_file()

  $object->to_xml_file($fileName, %options);

OBJECT METHOD that may be called upon objects of your generated complex classes.

This method writes the XML contents of a generated complex class in a file given by the first argument '$fileName'.

For the %options please see "to_xml_dom".

For a class corresponding to a global element:

        $object->to_xml_file('/tmp/country.xml');

or, for a class corresponding to complex type definition:

        $object->to_xml_fh('/tmp/country.xml', name=>'country'); # Assuming you want your ROOT element to be called 'country'.

No validation occurs proir to storage. If you want that, please do it yourself beforehand using "xml_validate" or "is_xml_valid".

The 'encoding' option is 'UTF-8' by default.

.

to_xml_fragment()

  $object->to_xml_fragment(%options);

OBJECT METHOD that may be called upon objects of your generated complex classes.

This method generates the fragment XML contents of a generated complex class and returns the resulting string. The difference between this method and "to_xml_string" is that this method calls the toString method on the root DOM node rather than the DOM DOCUMENT. Presumably, this will result in the absence of the ?xml tag with version and the encoding information in the beginning of the string.

For the %options please see "to_xml_dom".

For a class corresponding to a global element:

        $object->to_xml_fragment();

or, for a class corresponding to complex type definition:

        $object->to_xml_fragment(name=>'country'); # Assuming you want your ROOT element to be called 'country'.

No validation occurs proir to storage. If you want that, please do it yourself beforehand using "xml_validate" or "is_xml_valid".

The 'encoding' option is 'UTF-8' by default.

.

to_xml_string()

  $object->to_xml_string(%options);

OBJECT METHOD that may be called upon objects of your generated complex classes.

This method generates the XML contents of a generated complex class and returns the resulting string corresponding to an XML document. The difference between this method and "to_xml_fragment" is that this method calls the toString method on the DOM DOCUMENT node rather than the root DOM node (element).

For the %options please see "to_xml_dom".

For a class corresponding to a global element:

        $object->to_xml_string();

or, for a class corresponding to complex type definition:

        $object->to_xml_string(name=>'country'); # Assuming you want your ROOT element to be called 'country'.

No validation occurs proir to storage. If you want that, please do it yourself beforehand using "xml_validate" or "is_xml_valid".

The 'encoding' option is 'UTF-8' by default.

.

to_xml_url()

  $object->to_xml_url($url, %options);

OBJECT METHOD that may be called upon objects of your generated complex classes.

This method writes the XML contents of a generated complex class in a URL given by the first argument '$url'(either a string or a URI object) via the HTTP PUT method.

Note that LWP::UserAgent does not currently support the PUT method on file URLs. So if you try this on a file URL, the method will die.

For the %options please see "to_xml_dom".

For a class corresponding to a global element:

        $object->to_xml_url(URI->new('http://www.example.com/country.xml'));

or, for a class corresponding to complex type definition:

        $object->to_xml_url('http://www.example.com/country.xml', name=>'country'); # Assuming you want your ROOT element to be called 'country'.

No validation occurs proir to storage. If you want that, please do it yourself beforehand using "xml_validate" or "is_xml_valid".

The 'encoding' option is 'UTF-8' by default.

.

CLASS METHODS

is_xml_field_singleton()

  $bool = $class->is_xml_field_singleton($fieldName);

CLASS METHOD, but may also be called directly on an OBJECT.

'is_xml_field_singleton' will return TRUE if the field (attribute or child element) given by the $fieldName parameter corresonds to a child element with a 'maxOccurs' of '1' or 'undef'. A field that corresponds to an attribute will always return TRUE as attributes cannot have multiple values.

  $bool = $object->is_xml_field_singleton('city');      # assuming there is an attribute or child element called 'city'.

Note that the current value of the corresponding field is irrelevant for this method. It is the W3C schema information that matters.

See "is_xml_field_multiple" for more info.

.

is_xml_field_multiple()

  $className = $class->xml_field_class($fieldName);

CLASS METHOD, but may also be called directly on an OBJECT.

'is_xml_field_multiple' will return the negation of the boolean value returned by "is_xml_field_singleton". See "is_xml_field_singleton" for more information. A field that corresponds to an attribute will always return FALSE as attributes cannot have multiple values.

  $bool = $object->is_xml_field_multiple('city');       # assuming there is an attribute or child element called 'city'.

As a side note, notice that child elements that can potentially have multiple values will always be put in a XML::Pastor::NodeArray object when being read from XML, or when grabbed. This is regardless of the actual multiplicity of the current value of the field. That is, the multiplicity depends only on the 'maxOccurs' property defined in the W3C Schema.

XML::Pastor::NodeArray objects have some magical properties that occur thanks to hash access overloading and the AUTOLOAD method that enable them to be used as an array of fields or as if it were a reference to the first node in the array. See XML::Pastor::NodeArray for more details.

When writing to or validating XML, XML::Pastor is quite forgiving. Non-array (singleton) values are accepted as if they were an array having only one item inside.

.

xml_field_class()

  $className = $class->xml_field_class($fieldName);

CLASS METHOD, but may also be called directly on an OBJECT.

'xml_field_class' returns the class name for a given field (attribute or child element) by doing a look-up in the META W3C Schema type information via XmlSchemaType class data accessor.

If the field given by the $fieldName parameter cannot be found, the method will return undef.

When defined, the returned class name, which is typically the name of generated class, is guaranteed to be a descendent of either XML::Pastor::ComplexType or XML::Pastor::SimpleType.

  $class = $country->xml_field_class('city');   # assuming there is an attribute or child element called 'city'.
  $city  = $class->new(name=>'Paris');

This is the preferred method of obtaining class names for child elements or attributes instead of hard-coding them in your program. This way, your program only knows about the names of classes corresponding to global elements and the rest is obtained at run-time via xml_field_class.

.

CLASS DATA ACCESSORS

XmlSchemaType()

  my $type = $class->XmlSchemaType()

CLASS METHOD, but may also be called directly on an OBJECT.

XML::Pastor::Type defines (thanks to Class::Data::Inheritable) a class data acessor XmlSchemaType which returns undef.

This data accessor is set by each generated simple class to the meta information coming from your W3C Schema. This data is of class XML::Pastor::Schema::ComplexType or XML::Pastor::Schema::SimpleType.

You don't really need to know much about XmlSchemaType. It's used internally by Pastor's XML binding and validation methods as meta information about the generated class.

OTHER METHODS

grab()

  $field = $object->grab($fieldName);

'grab' will return the value of the field (attribute or child element) given by the $fieldName parameter. If the field does not exist, it will be automatically created (cally 'new()' on the right class) and stuffed into the complex object.

  $field = $object->grab('code');       #assuming there is an attribute or child element called 'code'.

Normally, you use the corresponding accessor method to get at the field (attribute or child element) of your choosing. The accessor will normally return 'undef' when the corresponding field does not exist in the object.

Sometimes, this is not what you desire. For example, when you will change the value of the field after reading it anyway, or when you will manipulate a child element of the field after calling the accessor anyway. This is where grab comes into play.

.

is_xml_valid()

  $bool = $object->is_xml_valid();

OBJECT METHOD.

'is_xml_valid' is similar to "xml_validate" except that it will not die on failure. Instead, it will just return FALSE (0).

The implementation of this method is very simple. Currently, it just calls "xml_validate" in an eval block and will return FALSE (0) if "xml_validate" dies. Otherwise, it will just return the same value as "xml_validate".

In case of failure, the contents of the special variable $@ will be left untouched in case you would like to access the error message that resulted from the death of "xml_validate".

.

xml_validate()

        $object->xml_validate();        # Will die on failure

OBJECT METHOD.

When overriden by the descendants, 'xml_validate' validates a Pastor XML object (of a generated class) with respect to the META information that had originally be extracted from your original W3C XSD Schema.

On sucess, xml_validate returns TRUE (1). On failure, it will die on you on validation errors.

At this stage, xml_validate simply returns the vaue returned by "xml_validate_further" which should perform extra checks. For XML::Pastor::Type this always returns TRUE, but some builtin types actually perform some extra validation during this call.

On sucess, xml_validate returns TRUE (1). On failure, it will die on you on validation errors.

The W3C recommendations have been observed as closely as possible for the implementation of this method. Neverthless, it remains somewhat more relaxed and easy compared to Castor for example.

One important note is that extra fields (those that do not correspond to an attribute or child element as defined by W3C schema) that may be present in the object are simply ignored and left alone. This has the advantage that you can actually store state information in the generated objects that are not destined to XML storage.

Another important behavior is the fact that even when you have multiple child elements for one that should have been a singleton, this does not trigger an error. Instead, only the first one is considered.

The absence of a required field (attribute or child element) is an error however. Furthermore, the validity of each attribute or child element is also checked by calling xml_validate on their respective classes even if you have only put a scalar in those. This means that such objects are created during validation on the fly whose values are set to the scalar present. But such validation induced objects are not stored back to the object and the scalars are left alone.

xml_validate_further()

        $object->xml_validate_further();        # Never called directly.

OBJECT METHOD.

'xml_validate_further' should perform extra validation on a Pastor XML object (of a generated class).

It is called by "xml_validate" after performing rutine validations.

This method should return TRUE(1) on success, and die on failure with an error message.

For XML::Pastor::Type, this method simple returns TRUE(1).

This method may be, and is indeed, overriden by subclasses. Several builtin classes like like XML::Pastor::Builtin::date and XML::Pastor::Builtin::dateTime override this method.

BUGS & CAVEATS ^

There no known bugs at this time, but this doesn't mean there are aren't any. Note that, although some testing was done prior to releasing the module, this should still be considered alpha code. So use it at your own risk.

Note that there may be other bugs or limitations that the author is not aware of.

AUTHOR ^

Ayhan Ulusoy <dev(at)ulusoy(dot)name>

COPYRIGHT ^

  Copyright (C) 2006-2007 Ayhan Ulusoy. All Rights Reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO ^

See also XML::Pastor, XML::Pastor::ComplexType, XML::Pastor::SimpleType

If you are curious about the implementation, see XML::Pastor::Schema::Parser, XML::Pastor::Schema::Model, XML::Pastor::Generator.

If you really want to dig in, see XML::Pastor::Schema::Attribute, XML::Pastor::Schema::AttributeGroup, XML::Pastor::Schema::ComplexType, XML::Pastor::Schema::Element, XML::Pastor::Schema::Group, XML::Pastor::Schema::List, XML::Pastor::Schema::SimpleType, XML::Pastor::Schema::Type, XML::Pastor::Schema::Object

syntax highlighting: