473,396 Members | 2,121 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

search for the right OOP pattern

Dormilich
8,658 Expert Mod 8TB
Hi guys,

I'm want to write a class for validating xml files, but I'm not sure about the pattern the class shall have.

what I have so far:
a class that's doing XSLT transformation:
Expand|Select|Wrap|Line Numbers
  1. class XSLTransform
  2. {
  3.   __construct() // checking if files are loaded from file or string
  4.   load() // loading XML & XSL files/strings
  5.   process() // doing transformation
  6.   checkResult() // well...
  7. }
in the load() method I check the XML files for validaty too, but that's taking too long (4 - 10s) so I decided to do the validation only when the files were recently changed. which leaves me with the task of storing the last validation results.

Now the problem.
in every call of this class I need the validation file to be checked if I have to do validation or not (basicly if the last successful validation is after the last modified time). I'd like to create a class (or an instance of a class) that holds the complete validation results (better than reading the file each time).

But which pattern should that class be? I thought of either singleton or registry pattern.
singleton
+ file reading while instantiation
– more (complex) code
registry
+ less code
+ can be deserialized (as a whole)
– needs external initialization

what do you think about that? or do you have a better idea than I?

thanks
Dec 20 '08 #1
5 1452
pbmods
5,821 Expert 4TB
Heya, Dormi.

You'll need to save a timestamp somewhere for each file and compare it with the modification time of that file when you load it.

My suggestion is to build it directly into the XSLTransform class (consider storing the timestamps in a SQLite database or flat file). If you need this functionality available to other classes, you might try a static XMLLoader or similar class.

WRT to validation speed, check out DOMDocument->schemaValidate() (http://php.net/domdocument.schemavalidate).
Dec 21 '08 #2
Dormilich
8,658 Expert Mod 8TB
@pbmods
that would require the XSLTransform class to be an abstract or singleton class... (I'll go for a file)

@pbmods
is XML Schema validation that much faster? the long validation times originate from a complex DTD (using several parameter entities).
Dec 21 '08 #3
pbmods
5,821 Expert 4TB
@Dormilich
No idea. The only reason that I suggested it is because DOMDocument's code is compiled C code, which runs faster than interpreted PHP code. On the other hand, your code might be tailored to your specific application so that it'll jump through fewer hoops. YMMV, really.
Dec 22 '08 #4
Dormilich
8,658 Expert Mod 8TB
@pbmods
currently I'm using DOMDocument->validate();
current DTD
Dec 22 '08 #5
Dormilich
8,658 Expert Mod 8TB
@pbmods
after some rewriting (and not as many errors as I expected) I got it working. runs like a flash (total page request time ~50 ms).

for those interested in the code (though comments and improvements are welcome):
Expand|Select|Wrap|Line Numbers
  1. class XSLTransform extends Validator
  2. {
  3.     private static $instance  = NULL;
  4.     private static $inDOM_xml = NULL;
  5.     private static $inDOM_xsl = NULL;
  6.     private $xml_loaded = false;
  7.     private $xsl_loaded = false;
  8.     public  $emptyResult = XSLT_FORCE_RESULT;
  9.  
  10.     private function __construct() {}
  11.     private function __clone() {}
  12.  
  13.     public static function getInstance($source_file = NULL)
  14.     {
  15.         if (self::$instance === NULL)
  16.         {
  17.             self::$instance  = new self;
  18.             self::$inDOM_xml = new DOMDocument();
  19.             self::$inDOM_xsl = new DOMDocument();
  20.             parent::load($source_file);
  21.         }
  22.         return self::$instance;
  23.     }   
  24.  
  25.     public function loadXML($file, $f_isFile = true)
  26.     {
  27.         $b_load = ($f_isFile) ? self::$inDOM_xml->load(XML_DIR . $file) : self::$inDOM_xml->loadXML($file);
  28.  
  29.         if (!$b_load)
  30.         {
  31.             $emsg = "Die Datei '$file' konnte nicht geladen werden.";
  32.             throw new ProcException(30, __METHOD__, $emsg);
  33.         }
  34.  
  35.         $this->xml_loaded = true;
  36.  
  37.         if ($this->requireValidation($file))
  38.         {
  39.             if (self::$inDOM_xml->validate())
  40.             {
  41.                 $this->setTime($file);
  42.             }
  43.             else
  44.             {
  45.                 $emsg = "Die Datei '$file' entspricht nicht der DTD, bzw. es liegt ein DTD Ladefehler vor.";
  46.                 trigger_error($emsg, E_USER_WARNING);
  47.             }
  48.         }
  49.     }
  50.  
  51.     public function loadXSL($file, $f_isFile = true)
  52.     {
  53.         $b_load = ($f_isFile) ? self::$inDOM_xsl->load(XSL_DIR . $file) : self::$inDOM_xsl->loadXML($file);
  54.  
  55.         if (!$b_load)
  56.         {
  57.             $emsg = "Die Datei '$file' konnte nicht geladen werden.";
  58.             throw new ProcException(30, __METHOD__, $emsg);
  59.         }
  60.  
  61.         $this->xsl_loaded = true;
  62.     }
  63.  
  64.     public function Process($param = array())
  65.     {
  66.         if (!$this->xml_loaded or !$this->xsl_loaded)
  67.         {
  68.             return NULL;
  69.         }
  70.  
  71.         $inXSL_proc = new XSLTProcessor();
  72.  
  73.         foreach ($param as $key => $value)
  74.         {
  75.             $inXSL_proc->setParameter('', $key, $value);
  76.         }
  77.  
  78.         $inXSL_proc->importStyleSheet(self::$inDOM_xsl); 
  79.         $result = $inXSL_proc->transformToXML(self::$inDOM_xml);
  80.  
  81.         $this->xml_loaded = false;
  82.         $this->xsl_loaded = false;
  83.  
  84.         $this->checkResult($result);
  85.  
  86.         return $result; 
  87.     }
  88.  
  89.     private function checkResult($data)
  90.     { 
  91.         if ($data === false)
  92.         {
  93.             $emsg = "Fehler bei der XSL Transformation. Fehler bei der Verarbeitung. (z.B. ungültiger XPath)";
  94.             throw new ProcException(30, __METHOD__, $emsg);
  95.         }
  96.  
  97.         if (empty($data) and !$this->emptyResult)
  98.         {
  99.             $emsg = "Fehler bei der XSL Transformation, leeres Ergebnis. Eingaben prüfen!";
  100.             throw new ProcException(40, __METHOD__, $emsg);
  101.         }
  102.     }
  103. }
Expand|Select|Wrap|Line Numbers
  1. abstract class Validator
  2. {
  3.     private $changed   = false;
  4.     private static $validated = array();
  5.     public  static $source    = NULL;
  6.  
  7.     function __destruct()
  8.     {
  9.         if ($this->changed)
  10.         {
  11.             $wddx_string = wddx_serialize_value(self::$validated, "validation timestamps");
  12.             if ($wddx_string !== false)
  13.             {
  14.                 $fh = fopen(self::$source, "w") or die("<div>Speichern der neuen Validation (Datei öffnen) gescheitert.</div>");
  15.                 fwrite($fh, $wddx_string) or die("<div>Speichern der neuen Validation (Datei speichern) gescheitert.</div>");
  16.                 fclose($fh);
  17.             }
  18.         }
  19.     }
  20.  
  21.     protected static function load($src_file = NULL)
  22.     {
  23.         self::$source = ($src_file) ? $src_file : "validation.xml";
  24.         if (file_exists(self::$source))
  25.         {
  26.             $inWDDX = new WDDXProcess(__CLASS__);
  27.             $inWDDX->loadFile(self::$source);
  28.             self::$validated = $inWDDX->isResultArray(XSLT_EMPTY_RESULT);
  29.         }
  30.     }
  31.  
  32.     public function setTime($file)
  33.     {
  34.         self::$validated[$file] = time();
  35.         $this->changed = true;
  36.     }
  37.  
  38.     public function requireValidation($file, $path = XML_DIR)
  39.     {
  40.         if (isset(self::$validated[$file]))
  41.         { 
  42.             if (file_exists($path . $file))
  43.             {
  44.                 $vtime = self::$validated[$file];
  45.                 if (filemtime($path . $file) < $vtime)
  46.                 {
  47.                     return false;
  48.                 }
  49.                 return true;
  50.             }
  51.             unset(self::$validated[$file]);
  52.             return NULL;
  53.         }
  54.         return true;
  55.     }
  56. }
Dec 22 '08 #6

Sign in to post your reply or Sign up for a free account.

Similar topics

8
by: Sharif T. Karim | last post by:
I am trying to do the following with my search script that looks for records in a mysql table. The following is an example of what I am trying to do. Text being searched: -- The brown fox...
11
by: Ben | last post by:
Greetings, I am looking for a way to search for and delete files based on a pattern mask. For example, the search method would find all files matching a certain pattern containing wildcards (e.g....
1
by: Les Juby | last post by:
A year or two back I needed a search script to scan thru HTML files on a client site. Usual sorta thing. A quick search turned up a neat script that provided great search results. It was fast,...
22
by: Phlip | last post by:
C++ers: Here's an open ended STL question. What's the smarmiest most templated way to use <string>, <algorithms> etc. to turn this: " able search baker search charlie " into this: " able...
2
by: ALI-R | last post by:
I am using the follwoing code to get all files which have txt as an extension but I get an error that your search pattern is not correct.it seems this fuction dosn't accept "*.txt" as search...
2
by: Alphonse Giambrone | last post by:
Is there a way to use multiple search patterns when calling Directory.GetFiles. For instance Directory.GetFiles("C:\MyFolder", "*.aspx") will return all files with the aspx extension. But what if...
1
by: Eric | last post by:
Hi: I have two files. I search pattern ":" from emails text file and save email contents into a database. Another search pattern " field is blank. Please try again.", vbExclamation + vbOKOnly...
2
by: sovixi | last post by:
Hi I want to search a text file (.txt) for words that I specify in my program. However, I can’t come up with any working solution. My program search string in a text file for ‘met|meeting|meets’ but...
9
by: Fabian Braennstroem | last post by:
Hi, I wrote a small gtk file manager, which works pretty well. Until now, I am able to select different file (treeview entries) just by extension (done with 'endswith'). See the little part...
30
by: Jrdman | last post by:
hi there can any one write a C code that search for files in a directory without using the windows apis(FindFirstFile() and FindNextFile()) or even has a small idea on how to do that. thanks.
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.