readme

来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· 代码 · 共 497 行 · 第 1/2 页

TXT
497
字号
XML Transformer TutorialBy Kristian K鰄ntopp and Sebastian Bergmann.0. This fileThis file is a supplementary document for the online documentation of theXML_Transformer PEAR package. It is not a comprehensive manual of methods andparameters, that's what the PEAR online documentation is good for.Instead, this document acts as a guide and tutorial to XML_Transformer andfriends. It aims at explaining the architecture of XML_Transformer and thechoices that governed its design. Also, it should contain a number of simpleapplications of XML_Transformer to illustrate its typical use.1. What is it good for?The XML Transformer is a system of PEAR classes that can be used to transformXML files into other XML files. The transformation is specified using PHPfunctions.We created XML Transformer because we were annoyed with the syntax andcapabilities of XSLT. XSLT is a very verbose language that needs many lines oftext to express even the simplest of algorithms. Also, XSLT is a functionallanguage offering all the drawbacks of languages of this class (variables areactually a kind of constant, recursion is needed to express many loops etc)without the advantages that come with such languages (closures, functions asfirst-order datatypes etc). Finally, XSLT is badly integrated into almost alldevelopment environments, offering little in the way of character manipulation,and nothing in the way to database access, image manipulation, flat file outputcontrol and so on.XML Transformer can do many things that linear (non-reordering) XSLT can. It cando some things XSLT can't (such as recursively reparsing its own output), and itcan utilize all PHP built-in functions and classes to do this. Transformationsare specified using the syntax of PHP with which you're already familiar, andthere is a simplified syntax to specify simple replacement transformations thatdoes not even need PHP at all.Since XML Transformer uses a SAX parser to do its work, it can't do anything aSAX parser can't do. That is, it cannot do reordering transformations in asingle pass. You won't be able to generate indices, tables of contents and othersummary operations in a single pass. If you run into such problems, think LaTeXand use the solutions LaTeX uses for this problems as well - we have recentlyadded support for multipassing, so that implementing such a mechanism shouldn'tbe too difficult. Also, we are providing the Docbook Namespace Handler as anexample for such mechanisms.Finally, we are considering an implementation of XML Transformer using a DOMparser and XPath queries to enable single pass reordering operations in PHP aswell.2. What are all these files and classes?2.1 XML_TransformerThe heart of the XML Transformer is defined in XML/Transformer.php. All the workis being done within the transform() method, which takes an XML string,transforms it and returns the transformed result.As transform() uses PHP's XML extension internally, the XML string must intheory be a well-formed XML fragment in order for the transformation to work.That is, it should be starting with a tag and ending with the same tag. Foryour convenience we internally wrap everything that is being transformedinto a <_>...</_> container in order to satisfy this requirement.To set up a transformation, you need to create an instance of the classXML_Transformer and then add options and transformations to it.  $t = new XML_Transformer();  $t->setDebug(true);  $t->overloadNamespace('php', new XML_Transformer_PHP);Options are added using the set-type methods setDebug(),setRecursiveOperation(), and setCaseFolding(). Transformations are added usingoverloadNamespace(). All of these options and then some can be set as parametersto the constructor. You'd be using an array that is being passed to the c'torfor this.  $t = new XML_Transformer(    'debug'                => true,    'overloadedNamespaces' => array(      'php',      new XML_Transformer_PHP    )  );2.2 XML_Transformer_CallbackRegistry and XML_UtilInternally, XML Transformer uses two auxiliary classes to do its work. One ofthem is the XML_Transformer_CallbackRegistry, which does all the bookkeeping forXML_Transformer, tracking which methods are to call for which namespace and soon. XML_Transformer_CallbackRegistry is a Singleton, and the instance ismaintained automatically by XML_Transformer. You never use it directly.The other used to be XML_Transformer_Util, which was later merged with othermethods and is now XML_Util, a PEAR package in its own right. Please referto the XML_Util documentation for more information on this class.2.3 XML_Transformer_NamespaceUsing XML_Transformer, all transformations are specified for namespaces. You mayspecifiy transformations for the empty namespace, that is, you may transformsimple tags such as <body/> or <p/>. The name of the empty namespace is '' or'&MAIN'.To make the definition of namespaces easy, we supply a classXML_Transformer_Namespace from which you can inherit (Note thatXML_Transformer_namespace is only one possible implementation for a namespace.You are free to choose a different implementation schema anytime, for example ifthe direct mapping of classes to namespaces is not applicable for yourdeployment scenario). The class is suitable for all non-nesting tags and theimplementation schemata shown here are suitable for non-nesting tags such as<img/> or <h1/>, but you'd need something more sophisticated to implement anesting structure such as <table/> which can contain itself.In order to define a tag called <tag />, you create a class and implementmethods called start_tag($attributes) and end_tag($cdata). These methods mustreturn the result of the transformation as strings, and it must be a valid XMLfragment. By our coding conventions, start_tag() never returns anything butonly records the tags attributes. All code is being generated in end_tag().That way we avoid problems with invalid XML in recursive parsing.class MyNamespace extends XML_Transformer_Namespace {  var $tag_attributes = array();  function start_tag($att) {    $this->tag_attributes = $att;    return '';  }  function end_tag($cdata) {    if (isset($this->tag_attributes['name'])) {      $name = $this->tag_attributes['name'];      $thline = "<tr><th>$name</th></tr>";    } else {      $thline = '';    }    return "<table>$thline<tr><td>$cdata</td></tr></table>";  }}This minimal sample implements a container tag called <...:tag name="headline"/>, which places its content in a table, and additionally supplied a tableheadline in a <th/> cell if an attribute "name" is present.The example is pretty much useless, but illustrates attribute capture, access tothe tags cdata content, and returning of results. Also, it illustrates how easynamespaces are created by inheriting from XML_Transformer_Namespace.To activate the namespace and assign it a namespace prefix, you'd useoverloadNamespace():  $t = new XML_Transformer(...);  $t->overloadNamespace('my', new MyNamespace());This tag can now be used as "<my:tag name='heading'>content</my:tag>".The XML_Transformer_Namespace class has a few instance variables which may comein handy in some cases. One of them is _transformer, which is indeed a referenceto the owning transformer.Another is an array _prefix, which is an enumeration of namespace prefixes ofthis namespace class. In our example above, that array would have just oneelement, $this->_prefix[0], and it would contain the string 'my'. As you mighthave guessed from the fact that _prefix is an array, we consider it legal toregister a single namespace class under multiple prefixes, if you can manage tokeep your references straight and not inadvertantly copy your instance. We havenot bothered to implement namespace scopes, though, as we should have were we inthe business of implementing the complete XML specification.The XML_Transformer has a handy feature where Namespaces are autoloaded andregistered under their default namespace names, if they define one. In order forautoloading to work, define an instance variable defaultNamespacePrefix as astring. This string is the prefix under which the namespace will register itselfwhen autoloading.Finally, a namespace may indicate that it requires two passes in order togenerate indicies or other data collections. If this is needed, the namespaceshould set secondPassRequired to true (default: false).2.3.1 Using autoloadingWe have supplied a number of subclasses to XML_Transformer_Namespace. Thesereside in a directory "./Transformer/Namespace" relative to the directory of theactual Transformer.php file itself, and can be autoloaded.In order to autoload namespaces, supply the flag "autoload" to your transformerconstructor. You may set the flag simply to "true" in order to load allNamespaces, or you may pass a single string or an array of strings indicatingthe namespaces you want to load.Namespaces are connected to their default prefixes, and in order for this towork they must define such prefixes in defaultNamespacePrefix.Example: $t = new XML_Transformer(            array(              'autoload' => true            )          ); Load all Namespaces $t = new XML_Transformer(            array(              'autoload' => 'PHP'            )          ); Load XML/Transformer/Namespace/PHP.php. $t = new XML_Transformer(            array(              'autoload' => array('PHP', 'Image', 'Anchor')            )          ); Load the indicated namespaces.Limitations of autoloading:- currently, there is no pathname support. Only classes in  "./Transformer/Namespace" can be autoloaded. Your project directories are  not searched.- currently, there is no separate method to trigger autoload.  You must specify autoloading as a flag to the constructor.2.4 supplied XML_Transformer NamespacesAll namespaces we supply are derived from XML_Transformer_Namespace and subjectto the limitations and interfaces of this baseclass.If you are looking into our code in order to write your own namespaces, werecommend you look into Anchor first. Anchor is your plain vanilla namespacewith no tricks and extra features.The DocBook namespace is an example of a two-pass namespace. If you have anapplication that needs to generate tables of contents, cross references or otherstuff that cannot be done without reordering, you should read DocBook as anexample.The Image namespace generates PNG images, and uses a local cache for this. That

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?