Commits

Anonymous committed 07bd88e

Added the bleading edge version as it stands now - passing all tests, but has
a bug.

Comments (0)

Files changed (17)

perl/modules/XML-SemanaticDiff/Changes

+Revision history for Perl extension XML::SemanticDiff.
+0.93  June 14 2001
+	- third (hopefully final) BETA
+	- more doc fixes.
+
+0.91  June 12 2001
+	- second BETA release.
+        - code cleanup.
+	- major doc fixes. 
+
+0.50  May 25 2001
+	- initial public BETA release. 
+
+0.01  Thu May 24 10:09:38 2001
+	- original version; created by h2xs 1.19
+

perl/modules/XML-SemanaticDiff/MANIFEST

+Changes
+Makefile.PL
+MANIFEST
+lib/XML/SemanticDiff.pm
+lib/XML/SemanticDiff/BasicHandler.pm
+eg/xmlsemdiff
+eg/camelids.xml
+eg/camelids2.xml
+t/01basic.t
+t/02load_xml.t
+t/03simple_compare.t
+t/04namespaces.t
+t/05simple_handler.t
+t/06pass_to_handler.t
+t/07pitest.t
+t/08nonexist_ns.t
+META.yml                                 Module meta-data (added by MakeMaker)

perl/modules/XML-SemanaticDiff/META.yml

+--- #YAML:1.0
+name:                XML-SemanticDiff
+version:             0.95
+abstract:            ~
+license:             ~
+generated_by:        ExtUtils::MakeMaker version 6.31
+distribution_type:   module
+requires:     
+    Digest::MD5:                   0
+    XML::Parser:                   0
+meta-spec:
+    url:     http://module-build.sourceforge.net/META-spec-v1.2.html
+    version: 1.2

perl/modules/XML-SemanaticDiff/Makefile.PL

+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+    'NAME'	=> 'XML::SemanticDiff',
+    'VERSION_FROM' => 'lib/XML/SemanticDiff.pm', # finds $VERSION
+    'PREREQ_PM' => {XML::Parser => '0', Digest::MD5 => '0'},
+    'EXE_FILES' => [ 'eg/xmlsemdiff' ],
+);

perl/modules/XML-SemanaticDiff/eg/camelids.xml

+<?xml version="1.0"?>
+<camelids>
+  <species name="Camelus bactrianus">
+    <common-name>Bactrian Camel</common-name>
+    <physical-characteristics>
+      <mass>450 to 500 kg.</mass>
+      <appearance>
+        The most noticeable feature of C. bactrianus is its two humps. At the hump, its average height is 213 cm (7 feet). A
+        thick, shaggy, dark brown to beige coat covers the camel during cold weather and is shed when the temperature
+        rises. Longer hair hangs from the neck and gives the appearance of a beard. Bushy eyebrows, a double row of eyelashes,
+        ears lined with hair and the ability to close nostrils and lips tightly serve as protection from harsh
+        conditions. Their tough, even-toed feet help them to cross the rocky desert in Asia and travel well through snow or
+        sand.
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+       <food-habits>
+         Camels are herbivores. Their preferred plants are dry, prickly, salty, and/or bitter. When other nutrient sources are
+         not available, the camel may feed on bones, other animals' skin, or different kinds of flesh. In more extreme
+         conditions, they may eat rope, sandals, and even tents. The camel's ability to feed on a wide range of foods allows
+         it to live in areas with sparse vegetation. With tough mouths that can withstand sharp objects such as thorns, the digestion process
+         begins. The first time food is swallowed it is not fully chewed. The partly masticated food (called cud) goes into
+         the stomach and later is brought back up for further chewing. Camels can go for several days without water. When water is 
+         available, they drink only to replace what is missing from their body. This amount can vary from nothing to 114
+         liters. Drinking the whole 114 liters of water takes only ten minutes. The camel also has the ability to quench its
+         thirst with salty or brackish water. In the winter months, plants alone provide water. A common misconception is that
+         the camel's humps are for water storage. In reality, the humps contain a large amount of fat and are use for nourishment 
+         when food is scarce. This feature gives the camel the capability to go many days without eating. Each hump can hold 
+         up to 36 kg of fat. The hump decreases in size and become flabby as its contents are metabolized. Depletion of the 
+         hump is directly linked to the time between eating and the amount of energy expended. Thus, the size of the hump
+         serves as an indication of C. bactrian's health, food supply and general well-being. The stomach is the camel's
+         water storage space. In it, water is retained in several sac-shaped containers. Approximately one and a half gallons
+         of water can be held in the stomach.
+       </food-habits>
+       <reproduction>
+         Mating season occurs in the fall, with inbreeding often involved in domesticated camels. The males during this time
+         are often violent and may bite, spit, or attempt to sit on other male camels. The age of sexual maturity varies, but
+         is usually reached at three to five years. Gestation lasts thirteen months. One or occasionally two calves are
+         produced. The female can give birth to a new calf every other year. The baby calf is precocial, having the ability to
+         stand at birth and walk only a few hours after. The young calf stays with its mother for three to five years, until
+         it reaches sexual maturity. 
+       </reproduction>
+       <behavior>
+         Domestic camels travel in caravans across the desert. An adult male acts as leader for a small group that may consist
+         of six to twenty others. Constantspeed must be maintained at all times while moving. To help ensure this tempo the
+         camels move by pacing. Pacing consists of two legs on the same sideof the body moving at once, creating a rolling
+         motion. This shifts the weight from side to side; a passenger may find this movement very uncomfortable. Camels also
+	 have the capability to run and can do so at ten to twenty miles per hour. 
+       </behavior>
+       <habitat>
+         The camel's habitat consists mainly of Asia's deserts. The temperature ranges from -29 degrees Celsius in the winter
+         to 38 degrees Celsius in the summer. 
+       </habitat>
+    </natural-history>
+    <conservation status="endangered">
+      <detail>
+        Camels were thought to be extinct in the wild until an expedition found some wild C. bactrianus in the Gobi desert in
+        1957. These wild groups are in the severedanger of going extinct and little is known about them. The estimated number
+        of wild camels ranges from 500 to 1000. 
+      </detail>
+    </conservation>
+  </species>
+  <species name="Camelus dromedarius">
+    <common-name>Dromedary, or Arabian Camel</common-name>
+    <physical-characteristics>
+      <mass>300 to 690 kg.</mass>
+      <appearance>
+        The dromedary camel is characterized by a long-curved neck, deep-narrow chest, and a single hump. The hump is composed
+        of fat bound together by fibrous tissue, acting as food storage in times of need. The size of the hump varies with the
+        nutritional status of the camel, becoming smaller to non-existent during times of starvation. The lips of the
+        dromedary camel are thickened to allow consumption of course, thorny plants. Dromedaries are typically caramel brown
+        or sandy brown in color, however, shades can range from almost black to nearly white. Hair length is longer on the
+        throat, shoulder, and hump areas. The feet of dromedaries are pad-shaped and adapted for traveling on sand. They can
+        be easily injured on sharp stones and are unsuitable for slippery or muddy conditions. Male dromedaries, in comparison
+        to females, are about 10% heavier, weighing 400-600 kg, and are about 10 cm taller at shoulder height, measuring
+        1.8-2.0 m. Additionally, male dromedaries have an inflatable soft palate which is used to attract females. Dromedary
+        camels have a total of 34 teeth, with a dental formula of 1/3; 1/1; 3/2; 3/3.
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+       <food-habits>
+         The dromedary camel is a herbivore. The camel eats primarily thorny plants, dry grasses and saltbush; however, it
+         will eat most anything that grows in  the desert (Oakland Zoo 1993). Dromedaries primarily browse, with shrubs and
+         forbs composing up to 70% of their diet. About 8-12 hours/day is  spent grazing with equal amounts spent ruminating
+         (Kohler-Rollefson 1991). When foraging, camels tend to spread over large areas and select only a  few leaves from
+         each plant. This type of feeding behavior reduces the stress on the plant communities and eases competition with
+         other arid region herbivores (Busch Gardens 1996). Additionally, dromedaries need 6 to 8 times as much salt as other
+         animals for adsorption and storage of water.  Consequently, 1/3 of their food intake must be halophytes. Dromedaries
+         browse up to a height of 3.5 m, breaking off branches or stripping off the  leaves in one movement. While browsing,
+         they use their lips to grasp the food, then chew each bite 40-50 times. The mouth is kept open while chewing  thorny
+         food (Kohler-Rollefson 1991)
+       </food-habits>
+       <reproduction>
+         The dromedary camel has a lifespan of about 40-50 years (Busch Gardens 1996). Females reach sexual maturity around
+         age 3 and mate around age 4  or 5. Males begin to rut by age 3, but do not reach full sexual maturity until age
+         6. Typically, males and females are seasonal breeders. Breeding occurs  in winter and overlaps with the rainy
+         season; both vary in respect to the camel's geographic range. The onset of the breeding season is believed to be
+         cued by nutritional status of the camel and the daylength. During competition for females, the males threaten each
+         other by making low noises with the  fleshy fold of their mouths, stand as tall as possible, and repeat a series of
+         head movements including lowering, lifting, and bending their necks  backwards. Upon confrontation, fighting males
+         attempt to bring their opponent to the ground by biting at his legs and taking the opponent's head in  between his 
+         jaws. Copulation time ranges from 7-35 minutes, averaging 11-15 minutes. The gestation period typically lasts for a
+         period of 15 months,  followed by the birth of a single calf. The calf can move freely by the end of the first
+         day. Maternal care generally lasts for 1 to 2 years. Calves typically  experience a growth rate of .19-.31 kg/day for
+         the first year. (Gauthier-Pilthers and Dagg 1981, Kohler-Rollefson 1991) 
+       </reproduction>
+       <behavior>
+         With the exception of rutting males, dromedaries show very little aggressive behavior. Confrontations among
+         dromedaries include pushing each other  with their whole body or lowered head and neck; snapping at each other
+         without biting; and occasionally vomiting cud when they are hurt or excited.  Dromedaries usually form groups of 2-20
+         individuals. The basic social unit is the family, consisting of one male, and one to several females, subadults,  and
+         young. The male within the family unit prevents contact between female camels within the family and stray males by
+         either standing or walking in between them, or by driving the stray males away. The male is the dominant member of
+         the family group and directs the family from the rear while the  females take turns leading. Dromedaries tend to
+         travel by walking single file. Dromedary camels find comfort in scratching parts of their body with their  front or
+         hind legs, or with their lower incisors. They are also often observed rubbing against trees. Additionally, they seem 
+         to like to roll in sand  (Gauthier-Pilthers and Dagg 1981, Kohler-Rollefson 1991). 
+       </behavior>
+       <habitat>
+         The camels prefer desert conditions characterized by a long dry season and a short rainy season. Introduction of the
+         dromedary into other climates has proven unsuccessful as the camel is sensitive to the cold and humidity (Nowak
+         1991). 
+       </habitat>
+    </natural-history>
+    <conservation status="no special status">
+      <detail>
+        Since the dromedary camel is domesticated, the camel has no special status in conservation (Busch Gardens 1996). 
+      </detail>
+    </conservation>
+  </species>
+  <species name="Lama glama">
+    <common-name>Llama</common-name>
+    <physical-characteristics>
+      <mass>130 to 155 kg.</mass>
+      <appearance>
+        Llamas feet are slender and their limbs are long. They have long, dense fine wool on their bodies. The hair on their
+        head, neck, and limbs is shorter than on their torso. Llamas have remarkable variety in their body sizes and
+        shapes. The larger  animals are more prevelant because of their use as "beasts of burden." Body length ranges from
+        153-200 cm, shoulder height from 100-125 cm, and tail length from 22-25 cm. The coloring of their fur is also
+        variable, ranging from all white,  to brown, yellow, blue and black, and sometimes with checks and spots. 
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+       <food-habits>
+         Llamas are herbivorous, feeding on many kinds of grasses and leaves.
+       </food-habits>
+       <reproduction>
+         Llamas reach sexual maturity at about 12-24 months. Females give birth every other year. Mating occurs in  August and
+         September. The gestation period is 348-368 days. Llamas produce one offspring at a time  (rarely two). The weight at
+         birth is 8-16 kg. Weaning occurs at 5-8 months. 
+       </reproduction>
+       <behavior>
+         The Lama glama lives only in domestication. They are mostly kept grazing freely on grasslands and scrublands at
+         elevations between 7,400-12,800 ft.  (2,300-4,000 m). Llamas are very graceful in their movements. They run with a
+         swinging stride, with their front and hind legs moving in unison on each  side. Llamas lie down to rest and
+         sleep. They are adept at spitting regurgitated food. Llamas use certain excretion sites that form dung heaps up to
+         2.4 meters in diameter. Fighting between males involves leg biting and "neck dominance." Copulation occurs while
+         animals are in a prone position. 
+       </behavior>
+       <habitat>
+         Llamas are found in deserts, mountainous areas, and grasslands.
+       </habitat>
+    </natural-history>
+    <conservation status="no special status">
+      <detail>
+        The population of llamas has declined since road building reduced their importance in transportation.
+      </detail>
+    </conservation>
+  </species>
+  <species name="Lama guanicoe">
+    <common-name>Guanaco</common-name>
+    <physical-characteristics>
+      <mass>115 to 140 kg.</mass>
+      <appearance>
+        They stand at 1,100 to 1,200mm at the shoulder and have slender bodies with long limbs and neck. The head is typical
+        of camelids with long, pointed ears and cleft, highly mobile lips. Their fur can be long, thick and wooly, especially
+        along the  flanks, chest and thighs. It is reddish-brown dorsally, and the underparts are white. 
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+       <food-habits>
+         Guanacos are herbivores that can inhabit dry areas and forego drinking for long periods. They are versatile foragers,
+         both browsing and grazing on grasses and plants. 
+       </food-habits>
+       <reproduction>
+         Females are apparently induced ovulators, and especially in the southern end of the range breeding reaches a peak in
+         February. Young are born in December to February after an eleven month gestation period. They weigh 8-15kg at birth
+         and nurse for eleven to fifteen months. Usually females do not breed until there third year. 
+       </reproduction>
+       <behavior>
+         There are three types of social groups: family groups, male troops, and solitary males. A family band is composed of
+         a single breeding male, several  females, and offspring. Males limit the size of their group by driving out young
+         males of six to twelve months and driving off males and sometimes  females trying to enter the group. Males defend a
+         territory that the group resides on, and the territory is demarcated by large communal defecation piles.  Only about
+         18% of males are in a family group; the others are in bands or solitary. The all-male bands are generally made up of
+         young males. Males in  these herds learn fighting ability through play fights. The solitary males tend to be mature
+         males looking for females or herds to take over. 
+       </behavior>
+       <habitat>
+         Guanacos inhabit grasslands and shrublands from sea level to 4,000m. Occasionally they winter in forests.
+       </habitat>
+    </natural-history>
+    <conservation status="special concern">
+      <detail>
+        Guanacos have had their numbers drastically reduced due to human pressures of habitat encroachment, habitat
+        destruction, and hunting. In addition, climatic changes are also blamed for decreases in population size and range. 
+      </detail>
+    </conservation>
+  </species>
+  <species name="Vicugna vicugna">
+    <common-name>Vicuna</common-name>
+    <physical-characteristics>
+      <mass>35 to 65 kg.</mass>
+      <appearance>
+        The vicuna is the smallest living species among the family Camelidae. Head and body length is 1,250-1,900 mm, tail
+        length is 150-250mm, and shoulder height is 700-1,100mm. A slender body and relatively long neck and limbs give a
+        vicuna an elegant appearance. The ears are long, pointed, and narrow. The head is round and yellowish to red-brown in
+        color. The long neck has yellowish red bib. The underside and inner parts of the flanks are dirty white. A strange
+        mane, 20-30cm long, with silky-white hair adorns the chest. Overall, the pelage is uniform and soft. Compared to the
+        similar-looking Lama guanicoe, the vicuna is one fourth the size, its body is paler, and it lacks callosities on the
+        inner sides of the forelimbs. Relative weight of the brain is greater than that of the guanaco. Among living
+        artiodactyls, vicunas  have unique, rodent-like incisors that are covered with enamel on only one side. Features
+        believed to be adaptations to  high altitudes include a large heart, specialized blood cells with hemoglobin of
+        greater affinty for oxygen, and a weight that  is 50 percent heavier than other mammals of the same size. Vision and
+        hearing is good, although the former is far more  developed. Olfaction is fairly poor. Nowak (1991), Grizmek (1990). 
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+      <food-habits>
+        The vicuna is strictly a grazer. Its diet consist of mostly short perennial grasses. The incisors are specially
+        adapted to its diet. They are large and  continuously growing as in rodents. The young often graze while lying
+        down. Both young and adults chew cud when they are at rest. Unlike most other  camelids, the vicuna requires daily
+        intake of water. Therefore, when selecting a territory, it searches an area with favorable watering sites. The average
+        feeding range is 184ha. Nowak (1991), Grizmek (1990), MacDonald (1984).
+      </food-habits>
+      <reproduction>
+        Mating begins in March and April. They mate while lying down on their chests, and copulation lasts 10-20
+        minutes. After 330-350 days of gestation  period, a female gives birth to a single offspring of 4-6 kg in February and
+        March. The female gives birth in a standing position, and it neither licks nor  eats the afterbirth. The mother mates
+        soon after giving birth. The young is mobile after just 15 minutes at birth. It remains close aside its mother for at
+        least 8 months. It continues to suckle until it reaches 10 months. Young females at this stage are expelled from the
+        herd by the dominant male. For  young males, this happens at 4-9 months. Expelled females are usually accepted into
+        another group. Females are capable of mating when they reach 2  years. Some are still reproductively active at 19
+        years. Vicunas in the wild live up to 15-20 years. In captivity, an individual was reported to have lived  24
+        years. MacDonald (1984), Nowak (1991), Grizmek (1990).
+      </reproduction>
+      <behavior>
+        Vicunas are alert and shy animals that flee very rapidly. They are capable of running 47 km/hr at an elevation of
+        4,500 meters. Movement is extremely  graceful compared to any other hoofed animal. When in danger, vicunas make a
+        clear, whistling sound. The dominant male warns its herd with an alarm  call, and positions itself between the threat
+        and the members. A single dominant male leads a group of females and juveniles. It determines the range of  the
+        territory and group membership, and it drives other males away from the family. The territorial male keeps its members
+        closely together at a distance of no more than 160ft. Group members display submission to the male by laying their
+        neck over the back. Family groups are closed societies,  excluding alien males and, at times, preventing even young
+        females from joining. The average size of a family is 6-10 individuals depending on the  feeding condition in the
+        territory. Vicunas are one of the few ungulates to possess a feeding territory and a separate sleeping territory. They
+        are diurnal,  and at night they retreat to their sleeping areas at higher altitudes. Adult males that do not lead any
+        herd become either solitary, or they form a large  group of 30 or even 150 individuals. However, there is low
+        cohesiveness among the members of these bachelor herds, and hierarchy is absent. Nowak  (1991), Grizmek (1990). 
+      </behavior>
+      <habitat>
+        Vicunas are found in semiarid rolling grasslands and plains at altitudes of 3,500-5,750 meters. These lands are
+        covered with short and tough vegetation.  Due to their daily water demands, vicunas live in areas where water is
+        readily accessible. Climate in the habitat is usually dry and cold. Nowak (1991),  Grizmek (1990).
+      </habitat>
+    </natural-history>
+    <conservation status="endangered">
+      <detail>
+        The vicuna is classified as vulnerable by the IUCN, and as endangered by the USDI. During the period of the Incas, the
+        total population reached 1.5 million. With the fall of the empire, the number dropped dramatically due to massive
+        slaughter by the conquerors and the settlers. By 1960, the number decreased to only 6,000. Recent efforts of
+        establishing national parks and organizations for protection of vicunas have brought the population back up to
+        125,000. About half of this number live at the Pampas Galeras National Vicuna Reserve in Peru. Nowak (1991), Grzimek
+        (1990). 
+      </detail>
+    </conservation>
+  </species>
+</camelids>

perl/modules/XML-SemanaticDiff/eg/camelids2.xml

+<?xml version="1.0"?>
+<camelids>
+  <species name="Camelus bactrianus">
+    <common-name>Bactrian Camel</common-name>
+    <physical-characteristics>
+      <appearance>
+        The most feature of C. bactrianus is its two humps. At the hump, its average height is 213 cm (7 feet). A
+        thick, shaggy, dark brown to beige coat covers the camel during cold weather and is shed when the temperature
+        rises. Longer hair hangs from the neck and gives the appearance of a beard. Bushy eyebrows, a double row of eyelashes,
+        ears lined with hair and the ability to close nostrils and lips tightly serve as protection from harsh
+        conditions. Their tough, even-toed feet help them to cross the rocky desert in Asia and travel well through snow or
+        sand.
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+       <food-habits>
+         up to 36 kg of fat. The hump decreases in size and become flabby as its contents are metabolized. Depletion of the 
+         hump is directly linked to the time between eating and the amount of energy expended. Thus, the size of the hump
+         serves as an indication of C. bactrian's health, food supply and general well-being. The stomach is the camel's
+         water storage space. In it, water is retained in several sac-shaped containers. Approximately one and a half gallons
+         of water can be held in the stomach.
+       </food-habits>
+       <reproduction>
+         it reaches sexual maturity. 
+       </reproduction>
+       <habitat>
+         The camel's habitat consists mainly of Asia's deserts. The temperature ranges from -29 degrees Celsius in the winter
+         to 38 degrees Celsius in the summer. 
+       </habitat>
+    </natural-history>
+    <conservation status="endangered">
+      <detail>
+        Camels were thought to be extinct in the wild until an expedition found some wild C. bactrianus in the Gobi desert in
+        1957. These wild groups are in the severedanger of going extinct and little is known about them. The estimated number
+        of wild camels ranges from 500 to 1000. 
+      </detail>
+    </conservation>
+  </species>
+  <species name="Camelus dromedarius">
+    <common-name>Dromedary, or Arabian Camel</common-name>
+    <physical-characteristics>
+      <mass>300 to 690 kg.</mass>
+      <appearance>
+        The dromedary camel is characterized by a long-curved neck, deep-narrow chest, and a single hump. The hump is composed
+        of fat bound together by fibrous tissue, acting as food storage in times of need. The size of the hump varies with the
+        nutritional status of the camel, becoming smaller to non-existent during times of starvation. The lips of the
+        dromedary camel are thickened to allow consumption of course, thorny plants. Dromedaries are typically caramel brown
+        or sandy brown in color, however, shades can range from almost black to nearly white. Hair length is longer on the
+        throat, shoulder, and hump areas. The feet of dromedaries are pad-shaped and adapted for traveling on sand. They can
+        be easily injured on sharp stones and are unsuitable for slippery or muddy conditions. Male dromedaries, in comparison
+        to females, are about 10% heavier, weighing 400-600 kg, and are about 10 cm taller at shoulder height, measuring
+        1.8-2.0 m. Additionally, male dromedaries have an inflatable soft palate which is used to attract females. Dromedary
+        camels have a total of 34 teeth, with a dental formula of 1/3; 1/1; 3/2; 3/3.
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+       <food-habits>
+         The dromedary camel is a herbivore. The camel eats primarily thorny plants, dry grasses and saltbush; however, it
+         will eat most anything that grows in  the desert (Oakland Zoo 1993). Dromedaries primarily browse, with shrubs and
+         forbs composing up to 70% of their diet. About 8-12 hours/day is  spent grazing with equal amounts spent ruminating
+         (Kohler-Rollefson 1991). When foraging, camels tend to spread over large areas and select only a  few leaves from
+         each plant. This type of feeding behavior reduces the stress on the plant communities and eases competition with
+         other arid region herbivores (Busch Gardens 1996). Additionally, dromedaries need 6 to 8 times as much salt as other
+         animals for adsorption and storage of water.  Consequently, 1/3 of their food intake must be halophytes. Dromedaries
+         browse up to a height of 3.5 m, breaking off branches or stripping off the  leaves in one movement. While browsing,
+         they use their lips to grasp the food, then chew each bite 40-50 times. The mouth is kept open while chewing  thorny
+         food (Kohler-Rollefson 1991)
+       </food-habits>
+       <reproduction>
+         The dromedary camel has a lifespan of about 40-50 years (Busch Gardens 1996). Females reach sexual maturity around
+         age 3 and mate around age 4  or 5. Males begin to rut by age 3, but do not reach full sexual maturity until age
+         6. Typically, males and females are seasonal breeders. Breeding occurs  in winter and overlaps with the rainy
+         season; both vary in respect to the camel's geographic range. The onset of the breeding season is believed to be
+         cued by nutritional status of the camel and the daylength. During competition for females, the males threaten each
+         other by making low noises with the  fleshy fold of their mouths, stand as tall as possible, and repeat a series of
+         head movements including lowering, lifting, and bending their necks  backwards. Upon confrontation, fighting males
+         attempt to bring their opponent to the ground by biting at his legs and taking the opponent's head in  between his 
+         jaws. Copulation time ranges from 7-35 minutes, averaging 11-15 minutes. The gestation period typically lasts for a
+         period of 15 months,  followed by the birth of a single calf. The calf can move freely by the end of the first
+         day. Maternal care generally lasts for 1 to 2 years. Calves typically  experience a growth rate of .19-.31 kg/day for
+         the first year. (Gauthier-Pilthers and Dagg 1981, Kohler-Rollefson 1991) 
+       </reproduction>
+       <behavior>
+         With the exception of rutting males, dromedaries show very little aggressive behavior. Confrontations among
+         dromedaries include pushing each other  with their whole body or lowered head and neck; snapping at each other
+         without biting; and occasionally vomiting cud when they are hurt or excited.  Dromedaries usually form groups of 2-20
+         individuals. The basic social unit is the family, consisting of one male, and one to several females, subadults,  and
+         young. The male within the family unit prevents contact between female camels within the family and stray males by
+         either standing or walking in between them, or by driving the stray males away. The male is the dominant member of
+         the family group and directs the family from the rear while the  females take turns leading. Dromedaries tend to
+         travel by walking single file. Dromedary camels find comfort in scratching parts of their body with their  front or
+         hind legs, or with their lower incisors. They are also often observed rubbing against trees. Additionally, they seem 
+         to like to roll in sand  (Gauthier-Pilthers and Dagg 1981, Kohler-Rollefson 1991). 
+       </behavior>
+       <habitat>
+         The camels prefer desert conditions characterized by a long dry season and a short rainy season. Introduction of the
+         dromedary into other climates has proven unsuccessful as the camel is sensitive to the cold and humidity (Nowak
+         1991). 
+       </habitat>
+    </natural-history>
+    <conservation status="no special status">
+      <detail>
+        Since the dromedary camel is domesticated, the camel has no special status in conservation (Busch Gardens 1996). 
+      </detail>
+    </conservation>
+  </species>
+  <species name="Lama glama">
+    <common-name>Llama</common-name>
+    <physical-characteristics>
+      <mass>130 to 155 kg.</mass>
+      <appearance>
+        Llamas feet are slender and their limbs are long. They have long, dense fine wool on their bodies. The hair on their
+        head, neck, and limbs is shorter than on their torso. Llamas have remarkable variety in their body sizes and
+        shapes. The larger  animals are more prevelant because of their use as "beasts of burden." Body length ranges from
+        153-200 cm, shoulder height from 100-125 cm, and tail length from 22-25 cm. The coloring of their fur is also
+        variable, ranging from all white,  to brown, yellow, blue and black, and sometimes with checks and spots. 
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+       <food-habits>
+         Llamas are herbivorous, feeding on many kinds of grasses and leaves.
+       </food-habits>
+       <reproduction>
+         Llamas reach sexual maturity at about 12-24 months. Females give birth every other year. Mating occurs in  August and
+         September. The gestation period is 348-368 days. Llamas produce one offspring at a time  (rarely two). The weight at
+         birth is 8-16 kg. Weaning occurs at 5-8 months. 
+       </reproduction>
+       <behavior>
+         The Lama glama lives only in domestication. They are mostly kept grazing freely on grasslands and scrublands at
+         elevations between 7,400-12,800 ft.  (2,300-4,000 m). Llamas are very graceful in their movements. They run with a
+         swinging stride, with their front and hind legs moving in unison on each  side. Llamas lie down to rest and
+         sleep. They are adept at spitting regurgitated food. Llamas use certain excretion sites that form dung heaps up to
+         2.4 meters in diameter. Fighting between males involves leg biting and "neck dominance." Copulation occurs while
+         animals are in a prone position. 
+       </behavior>
+       <habitat>
+         Llamas are found in deserts, mountainous areas, and grasslands.
+       </habitat>
+    </natural-history>
+    <conservation status="no special status">
+      <detail>
+        The population of llamas has declined since road building reduced their importance in transportation.
+      </detail>
+    </conservation>
+  </species>
+  <species name="Lama guanicoe">
+    <common-name>Guanaco</common-name>
+    <physical-characteristics>
+      <mass>115 to 140 kg.</mass>
+      <appearance>
+        They stand at 1,100 to 1,200mm at the shoulder and have slender bodies with long limbs and neck. The head is typical
+        of camelids with long, pointed ears and cleft, highly mobile lips. Their fur can be long, thick and wooly, especially
+        along the  flanks, chest and thighs. It is reddish-brown dorsally, and the underparts are white. 
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+       <food-habits>
+         Guanacos are herbivores that can inhabit dry areas and forego drinking for long periods. They are versatile foragers,
+         both browsing and grazing on grasses and plants. 
+       </food-habits>
+       <reproduction>
+         Females are apparently induced ovulators, and especially in the southern end of the range breeding reaches a peak in
+         February. Young are born in December to February after an eleven month gestation period. They weigh 8-15kg at birth
+         and nurse for eleven to fifteen months. Usually females do not breed until there third year. 
+       </reproduction>
+       <behavior>
+         There are three types of social groups: family groups, male troops, and solitary males. A family band is composed of
+         a single breeding male, several  females, and offspring. Males limit the size of their group by driving out young
+         males of six to twelve months and driving off males and sometimes  females trying to enter the group. Males defend a
+         territory that the group resides on, and the territory is demarcated by large communal defecation piles.  Only about
+         18% of males are in a family group; the others are in bands or solitary. The all-male bands are generally made up of
+         young males. Males in  these herds learn fighting ability through play fights. The solitary males tend to be mature
+         males looking for females or herds to take over. 
+       </behavior>
+       <habitat>
+         Guanacos inhabit grasslands and shrublands from sea level to 4,000m. Occasionally they winter in forests.
+       </habitat>
+    </natural-history>
+    <conservation status="special concern">
+      <detail>
+        Guanacos have had their numbers drastically reduced due to human pressures of habitat encroachment, habitat
+        destruction, and hunting. In addition, climatic changes are also blamed for decreases in population size and range. 
+      </detail>
+    </conservation>
+  </species>
+  <species name="Vicugna vicugna">
+    <common-name>Vicuna</common-name>
+    <physical-characteristics>
+      <mass>35 to 65 kg.</mass>
+      <appearance>
+        The vicuna is the smallest living species among the family Camelidae. Head and body length is 1,250-1,900 mm, tail
+        length is 150-250mm, and shoulder height is 700-1,100mm. A slender body and relatively long neck and limbs give a
+        vicuna an elegant appearance. The ears are long, pointed, and narrow. The head is round and yellowish to red-brown in
+        color. The long neck has yellowish red bib. The underside and inner parts of the flanks are dirty white. A strange
+        mane, 20-30cm long, with silky-white hair adorns the chest. Overall, the pelage is uniform and soft. Compared to the
+        similar-looking Lama guanicoe, the vicuna is one fourth the size, its body is paler, and it lacks callosities on the
+        inner sides of the forelimbs. Relative weight of the brain is greater than that of the guanaco. Among living
+        artiodactyls, vicunas  have unique, rodent-like incisors that are covered with enamel on only one side. Features
+        believed to be adaptations to  high altitudes include a large heart, specialized blood cells with hemoglobin of
+        greater affinty for oxygen, and a weight that  is 50 percent heavier than other mammals of the same size. Vision and
+        hearing is good, although the former is far more  developed. Olfaction is fairly poor. Nowak (1991), Grizmek (1990). 
+      </appearance>
+    </physical-characteristics>
+    <natural-history>
+      <food-habits>
+        The vicuna is strictly a grazer. Its diet consist of mostly short perennial grasses. The incisors are specially
+        adapted to its diet. They are large and  continuously growing as in rodents. The young often graze while lying
+        down. Both young and adults chew cud when they are at rest. Unlike most other  camelids, the vicuna requires daily
+        intake of water. Therefore, when selecting a territory, it searches an area with favorable watering sites. The average
+        feeding range is 184ha. Nowak (1991), Grizmek (1990), MacDonald (1984).
+      </food-habits>
+      <reproduction>
+        Mating begins in March and April. They mate while lying down on their chests, and copulation lasts 10-20
+        minutes. After 330-350 days of gestation  period, a female gives birth to a single offspring of 4-6 kg in February and
+        March. The female gives birth in a standing position, and it neither licks nor  eats the afterbirth. The mother mates
+        soon after giving birth. The young is mobile after just 15 minutes at birth. It remains close aside its mother for at
+        least 8 months. It continues to suckle until it reaches 10 months. Young females at this stage are expelled from the
+        herd by the dominant male. For  young males, this happens at 4-9 months. Expelled females are usually accepted into
+        another group. Females are capable of mating when they reach 2  years. Some are still reproductively active at 19
+        years. Vicunas in the wild live up to 15-20 years. In captivity, an individual was reported to have lived  24
+        years. MacDonald (1984), Nowak (1991), Grizmek (1990).
+      </reproduction>
+      <behavior>
+        Vicunas are alert and shy animals that flee very rapidly. They are capable of running 47 km/hr at an elevation of
+        4,500 meters. Movement is extremely  graceful compared to any other hoofed animal. When in danger, vicunas make a
+        clear, whistling sound. The dominant male warns its herd with an alarm  call, and positions itself between the threat
+        and the members. A single dominant male leads a group of females and juveniles. It determines the range of  the
+        territory and group membership, and it drives other males away from the family. The territorial male keeps its members
+        closely together at a distance of no more than 160ft. Group members display submission to the male by laying their
+        neck over the back. Family groups are closed societies,  excluding alien males and, at times, preventing even young
+        females from joining. The average size of a family is 6-10 individuals depending on the  feeding condition in the
+        territory. Vicunas are one of the few ungulates to possess a feeding territory and a separate sleeping territory. They
+        are diurnal,  and at night they retreat to their sleeping areas at higher altitudes. Adult males that do not lead any
+        herd become either solitary, or they form a large  group of 30 or even 150 individuals. However, there is low
+        cohesiveness among the members of these bachelor herds, and hierarchy is absent. Nowak  (1991), Grizmek (1990). 
+      </behavior>
+      <habitat>
+        Vicunas are found in semiarid rolling grasslands and plains at altitudes of 3,500-5,750 meters. These lands are
+        covered with short and tough vegetation.  Due to their daily water demands, vicunas live in areas where water is
+        readily accessible. Climate in the habitat is usually dry and cold. Nowak (1991),  Grizmek (1990).
+      </habitat>
+    </natural-history>
+    <conservation status="endangered">
+      <detail>
+        The vicuna is classified as vulnerable by the IUCN, and as endangered by the USDI. During the period of the Incas, the
+        total population reached 1.5 million. With the fall of the empire, the number dropped dramatically due to massive
+        slaughter by the conquerors and the settlers. By 1960, the number decreased to only 6,000. Recent efforts of
+        establishing national parks and organizations for protection of vicunas have brought the population back up to
+        125,000. About half of this number live at the Pampas Galeras National Vicuna Reserve in Peru. Nowak (1991), Grzimek
+        (1990). 
+      </detail>
+    </conservation>
+  </species>
+</camelids>

perl/modules/XML-SemanaticDiff/eg/xmlsemdiff

+#!/usr/bin/perl -w
+
+#########################################
+# xmlsemdiff -- command-line freindly interface to
+#               XML::SemanticDiff
+#
+########################################
+
+use strict;
+use XML::SemanticDiff;
+my $diff = XML::SemanticDiff->new(keeplinenums => 1);
+
+my ($file1, $file2) = @ARGV;
+usage() unless defined $file1 and defined $file2;
+
+foreach my $change ($diff->compare($file1, $file2)) {
+    print "$change->{message} (between lines $change->{startline} and $change->{endline})\n";
+}
+
+sub usage {
+   die "usage: $0 one.xml two.xml \n";
+}
+
+exit;
+
+
+

perl/modules/XML-SemanaticDiff/lib/XML/SemanticDiff.pm

+package XML::SemanticDiff;
+
+use strict;
+use vars qw/$VERSION/;
+
+$VERSION = '0.95';
+
+use XML::Parser;
+
+sub new {
+    my ($proto, %args) = @_;
+    my $class = ref($proto) || $proto;
+    my $self = \%args;
+
+    require XML::SemanticDiff::BasicHandler unless defined $args{diffhandler};
+
+    bless ($self, $class);
+    return $self;
+}
+
+sub read_xml {
+    my $self = shift;
+    my $p = XML::Parser->new( Style => 'Stream',
+                              Pkg   => 'PathFinder',
+                              'Non-Expat-Options' => $self,
+                              Namespaces => 1);
+
+    my $doc = $_[0] !~ /\n/g && -f $_[0] ? $p->parsefile($_[0]) : $p->parse($_[0]);
+
+    return $doc;
+}
+
+sub _same_namespace
+{
+    my ($self, $to, $from) = @_;
+    
+    my $t_e = exists($to->{NamespaceURI});
+    my $f_e = exists($from->{NamespaceURI});
+    if (!$t_e && !$f_e)
+    {
+        return 1;
+    }
+    elsif ($t_e && $f_e)
+    {
+        return ($to->{NamespaceURI} eq $from->{NamespaceURI});
+    }
+    else
+    {
+        return 0;
+    }
+}
+# Okay, it's pretty basic...
+#
+# We flatten each doc tree to a Perl hash where the keys are "fully qualified" 
+# XPath expressions (/root[1]/element[3]) that represent the unique location
+# of each XML element, then compare the two hashes. 
+#
+# Just loop over all the elements of the first hash- if the same key exists
+# in the second, you compare the text and attributes and delete it. Any
+# keys not found in the second hash are declared 'missing', and any keys leftover
+# in the second hash after looping through the elements in the first are 'rogues'. 
+
+sub compare {
+    my $self = shift;
+    my ($from_xml, $to_xml) = @_;
+
+    my $from_doc = ref($from_xml) eq 'HASH' ? $from_xml : $self->read_xml($from_xml);
+    my $to_doc = $self->read_xml($to_xml);
+
+    my @warnings = ();
+
+    my $handler = $self->{diffhandler} || XML::SemanticDiff::BasicHandler->new(%$self);
+
+
+    # fire the init handler
+    push (@warnings, $handler->init($self)) if $handler->can('init');
+
+    # loop the elements
+    foreach my $element (sort keys (%$from_doc)) {
+
+        # element existence check
+        if (defined $to_doc->{$element}) {
+
+            # element value test
+            unless ($from_doc->{$element}->{TextChecksum} eq $to_doc->{$element}->{TextChecksum}) {
+                push (@warnings, $handler->element_value($element, 
+                                                         $to_doc->{$element}, 
+                                                         $from_doc->{$element}))
+                          if $handler->can('element_value');
+            }
+        
+            # namespace test
+            unless ($self->_same_namespace($from_doc->{$element},$to_doc->{$element})) {
+                push (@warnings, $handler->namespace_uri($element, 
+                                                         $to_doc->{$element}, 
+                                                         $from_doc->{$element}))
+                           if $handler->can('namespace_uri');
+            }
+    
+            # attribute tests
+            foreach my $attr (keys(%{$from_doc->{$element}->{Attributes}})) {
+ 
+                 # attr existence check
+                 if (defined ($to_doc->{$element}->{Attributes}->{$attr})) {
+
+                     # attr value test
+                     if ($to_doc->{$element}->{Attributes}->{$attr} ne $from_doc->{$element}->{Attributes}->{$attr}){
+                        push (@warnings, $handler->attribute_value($attr, 
+                                                                   $element, 
+                                                                   $to_doc->{$element},
+                                                                   $from_doc->{$element}))
+                              if $handler->can('attribute_value');
+                     }
+                     delete $to_doc->{$element}->{Attributes}->{$attr};
+                 }
+                 else {
+                     push (@warnings, $handler->missing_attribute($attr, 
+                                                                  $element, 
+                                                                  $to_doc->{$element}, 
+                                                                  $from_doc->{$element}))
+                           if $handler->can('missing_attribute'); 
+                 }                
+            }
+
+            # rogue attrs
+            foreach my $leftover (keys(%{$to_doc->{$element}->{Attributes}})) {
+                push (@warnings, $handler->rogue_attribute($leftover, 
+                                                           $element, 
+                                                           $to_doc->{$element}, 
+                                                           $from_doc->{$element}))
+                     if $handler->can('rogue_attribute');
+            }
+            
+            delete $to_doc->{$element};
+        }
+        else {  
+            push (@warnings, $handler->missing_element($element, $from_doc->{$element}))
+                      if $handler->can('missing_element');          
+        }
+    }
+
+    # rogue elements
+    foreach my $leftover ( keys (%$to_doc) ) {
+        push (@warnings, $handler->rogue_element($leftover, $to_doc->{$leftover})) 
+             if $handler->can('rogue_element');
+    }                 
+
+    push (@warnings, $handler->final($self)) if $handler->can('final');
+            
+    return @warnings;
+}
+
+1;
+
+package PathFinder;
+use strict;
+use Digest::MD5  qw(md5_base64);    
+my $descendents = {};
+my $position_index = {};
+my $char_accumulator = {};
+my $doc = {};
+my $opts = {};
+
+sub StartTag {
+    my ($expat, $element) = @_;
+    my %attrs = %_;
+            
+    my @context = $expat->context;
+    my $context_length = scalar (@context);
+    my $parent = $context[$context_length -1];
+    push (@{$descendents->{$parent}}, $element) if $parent;
+    $position_index->{"$element"}++;
+    my $test_context;
+ 
+    if (@context){
+        $test_context = '/' . join ('/', map { $_ . '[' . $position_index->{$_} . ']' } @context);
+    }   
+        
+    $test_context .= '/' . $element . '[' . $position_index->{$element} . ']';
+
+    $doc->{"$test_context"}->{NamespaceURI} = $expat->namespace($element) || "";
+    $doc->{"$test_context"}->{Attributes}   = \%attrs || {};
+    $doc->{"$test_context"}->{TagStart}     = $expat->current_line if $opts->{keeplinenums};
+
+}
+
+sub EndTag {
+    my ($expat, $element) = @_;
+    
+    
+    my @context = $expat->context;
+    my $test_context;
+            
+    if (@context){
+        $test_context = '/' . join ('/', map { $_ . '[' . $position_index->{$_} . ']' } @context);
+    }
+         
+    $test_context .= '/' . $element . '[' . $position_index->{$element} . ']';
+            
+    my $text;
+    if ( defined( $char_accumulator->{$element} )) { 
+        $text = $char_accumulator->{$element};
+        delete $char_accumulator->{$element};
+    }
+    $text ||= 'o';
+    
+#    warn "text is '$text' \n";
+#    my $ctx = Digest::MD5->new;
+#    $ctx->add("$text");
+#    $doc->{"$test_context"}->{TextChecksum} = $ctx->b64digest;
+
+    $doc->{"$test_context"}->{TextChecksum} = md5_base64("$text");
+    if ($opts->{keepdata}) {
+        $doc->{"$test_context"}->{CData} = $text;
+    }
+    
+    
+    if (defined ( $descendents->{$element})) {
+        my $seen = {};
+        foreach my $child (@{$descendents->{$element}}) {
+            next if $seen->{$child};
+            $seen->{$child}++;
+        }
+    }
+    
+    $doc->{"$test_context"}->{TagEnd} = $expat->current_line if $opts->{keeplinenums};
+
+    $position_index->{$element}--;        
+}
+
+sub Text {
+    my $expat = shift;
+    
+    my $element = $expat->current_element;
+    my $char = $_;
+    
+    $char =~ s/^\s*//;
+    $char =~ s/\s*$//;
+    $char =~ s/\s+/ /g;
+    $char_accumulator->{$element} .= $char if $char;
+    
+}
+        
+sub StartDocument {
+    my $expat = shift;
+    $doc = {};
+    $descendents = {};
+    $position_index = {};
+    $char_accumulator = {};
+    $opts = $expat->{'Non-Expat-Options'}
+}
+        
+sub EndDocument {
+    return $doc;
+}
+    
+sub PI {
+    my ($expat, $target, $data) = @_;
+    my $attrs = {};
+    $position_index->{$target}++;
+
+    foreach my $pair (split /\s+/, $data) {
+        $attrs->{$1} = $2 if $pair =~ /^(.+?)=["'](.+?)["']$/;
+    }
+
+    my $slug = '?' . $target . '[' . $position_index->{$target} . ']';
+
+    $doc->{$slug}->{Attributes} = $attrs || {};
+    $doc->{$slug}->{TextChecksum} = "1";
+    $doc->{$slug}->{NamespaceURI} = "";
+    $doc->{$slug}->{TagStart} = $expat->current_line if $opts->{keeplinenums};
+    $doc->{$slug}->{TagEnd} = $expat->current_line if $opts->{keeplinenums};
+
+}   
+
+1;
+__END__
+
+=head1 NAME
+
+XML::SemanticDiff - Perl extension for comparing XML documents.
+
+=head1 SYNOPSIS
+
+  use XML::SemanticDiff;
+  my $diff = XML::SemanticDiff->new();
+
+  foreach my $change ($diff->compare($file, $file2)) {
+      print "$change->{message} in context $change->{context}\n";
+  }
+
+  # or, if you want line numbers:
+
+  my $diff = XML::SemanticDiff->new(keeplinenums => 1);
+
+  foreach my $change ($diff->compare($file, $file2)) {
+      print "$change->{message} (between lines $change->{startline} and $change->{endline})\n";
+  }
+
+=head1 DESCRIPTION
+
+XML::SematicDiff provides a way to compare the contents and structure of two XML documents. By default, it returns a list of
+hashrefs where each hashref describes a single difference between the two docs.
+
+=head1 METHODS
+
+=head2 $obj->new([%options])
+
+Ye olde object constructor.
+
+The new() method recognizes the following options:
+
+=over 4
+
+=item * keeplinenums
+
+When this option is enabled XML::SemanticDiff will add the 'startline' and 'endline' properties (containing the line numbers
+for the reported element's start tag and end tag) to each warning. For attribute events these numbers reflect the start and
+end tags of the element which contains that attribute. 
+
+=item * keepdata
+
+When this option is enabled XML::SemanticDiff will add the 'old_value' and 'new_value' properties to each warning. These
+properties contain, surprisingly, the old and new values for the element or attribute being reported. 
+
+In the case of missing elements or attributes (those in the first document, not in the second) only the 'old_value' property
+will be defined. Similarly, in the case of rogue elements or attributes (those in the second document but not in the
+first) only the 'new_value' property will be defined. 
+
+Note that using this option will greatly increase the amount of memory used by your application.
+
+=item * diffhandler
+
+Taking a blessed object as it's sole argument, this option provides a way to hook the basic semantic diff engine into your own
+custom handler class. 
+
+Please see the section on 'CUSTOM HANDLERS' below.
+
+=back
+
+=head1 CUSTOM HANDLERS
+
+Internally, XML::SemanticDiff uses an event-based model somewhat reminiscent of SAX where the various 'semantic diff events'
+are handed off to a separate handler class to cope with the details. For most general cases where the user only cares about 
+reporting the differences between two docs, the default handler, XML::SemanticDiff::BasicHandler, will probably  
+suffice. However, it is often desirable to add side-effects to the diff process (updating datastores, widget callbacks,  
+etc.) and a custom handler allows you to be creative with what to do about differences between two XML documents and how
+those differences are reported back to the application through the compare() method.
+
+=head1 HANDLER METHODS
+
+The following is a list of handler methods that can be used for your custom diff-handler class.
+
+=head2 init($self, $diff_obj)
+
+The C<init> method is called immediately before the the two document HASHes are compared. The blessed XML::SemanticDiff object
+is passed as the sole argument, so any values that you wish to pass from your application to your custom handler can safely
+be added to the call to XML::SemanticDiff's constructor method.
+
+=head2 rogue_element($self, $element_name, $todoc_element_properties)
+
+The C<rogue_element> method handles those cases where a given element exists in the to-file but not in the from-file.
+
+=head2 missing_element($self, $element_name, $fromdoc_element_properties)
+
+The C<missing_element> method handles those cases where a given element exists in the from-file but not in the to-file.
+
+=head2 element_value($self, $element, $to_element_properties, $fromdoc_element_properties)
+
+The C<element_value> method handles those cases where the text data differs between two elements that have the same name,
+namespace URI, and are at the same location in the document tree. Note that all whitespace is normalized and the text from
+mixed-content elements (those containing both text and child elements mixed together) is aggregated down to a single value.
+
+=head2 namespace_uri($self, $element, $todoc_element_properties, $fromdoc_element_properties)
+
+The C<namespace_uri> method handles case where the XML namespace URI differs between a given element in the two
+documents. Note that the namespace URI is checked, not the element prefixes since <foo:element/> <bar:element/> and <element/> 
+are all considered equivalent as long as they are bound to the same namespace URI.
+ 
+
+=head2 rogue_attribute($self, $attr_name, $element, $todoc_element_properties)
+
+The C<rogue_attribute> method handles those cases where an attribute exists in a given element the to-file but not in the
+from-file.
+
+=head2 missing_attribute($self, $attr_name, $element, $todoc_element_properties, $fromdoc_element_properties)
+
+The C<missing_attribute> method handles those cases where an attribute exists in a given element exists in the from-file but
+not in the to-file.
+
+=head2 attribute_value($self, $attr_name, $element, $todoc_element_properties, $fromdoc_element_properties)
+
+The C<attribute_value> method handles those cases where the value of an attribute varies between the same element in both
+documents.
+
+=head2 final($self, $diff_obj)
+
+The C<final> method is called immediately after the two document HASHes are compared. Like the C<init> handler, it is passed a
+copy of the XML::SemanticDiff object as it's sole argument.
+
+Note that if a given method is not implemented in your custom handler class, XML::SemanticDiff will not complain; but it means
+that all of those events will be silently ignored. Consider yourself warned. 
+
+=head1 AUTHOR
+
+Kip Hampton, khampton@totalcinema.com
+
+=head1 COPYRIGHT
+
+Copyright (c) 2000 Kip Hampton. All rights reserved. This program is free software; you can redistribute it and/or modify it 
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+perl(1).
+
+=cut

perl/modules/XML-SemanaticDiff/lib/XML/SemanticDiff/BasicHandler.pm

+package XML::SemanticDiff::BasicHandler;
+
+use strict;
+use vars qw/$VERSION/;
+
+$VERSION = '0.93';
+
+sub new {       
+    my ($proto, %args) = @_;
+    my $class = ref($proto) || $proto;
+    my $self  = \%args;
+    bless ($self, $class);
+    return $self;
+}
+
+sub rogue_element {
+    my $self = shift;
+    my ($element, $properties) = @_;
+    my ($element_name, $parent) = parent_and_name($element);
+    my $info = {context => $parent,
+                message => "Rogue element '$element_name' in element '$parent'."};
+    
+    if ($self->{keeplinenums}) {
+        $info->{startline} = $properties->{TagStart};
+        $info->{endline}   = $properties->{TagEnd};
+    }
+ 
+    if ($self->{keepdata}) {
+        $info->{new_value} = $properties->{CData};
+    }    
+    return $info;
+}
+
+sub missing_element {
+    my $self = shift;
+    my ($element, $properties) = @_;
+    my ($element_name, $parent) = parent_and_name($element);
+    my $info = {context => $parent,
+                message => "Child element '$element_name' missing from element '$parent'."};
+                 
+    if ($self->{keeplinenums}) {
+        $info->{startline} = $properties->{TagStart};
+        $info->{endline}   = $properties->{TagEnd};
+    }
+    if ($self->{keepdata}) {
+        $info->{old_value} = $properties->{CData};
+    }
+    return $info;
+}
+
+sub element_value {
+    my $self = shift;
+    my ($element, $new_properties, $old_properties) = @_;
+    my ($element_name, $parent) = parent_and_name($element);
+
+    my $info = {context => $element,
+                message => "Character differences in element '$element_name'."};
+                       
+    if ($self->{keeplinenums}) {
+        $info->{startline} = $new_properties->{TagStart};
+        $info->{endline}   = $new_properties->{TagEnd};
+    }
+                  
+    if ($self->{keepdata}) {
+        $info->{old_value} = $old_properties->{CData};
+        $info->{new_value} = $new_properties->{CData};
+    }
+
+    return $info;
+}
+
+sub rogue_attribute {
+    my $self = shift;    
+    my ($attr, $element, $properties) = @_;
+    my ($element_name, $parent) = parent_and_name($element);
+    my $info = {context  => $element,
+                message  => "Rogue attribute '$attr' in element '$element_name'."};
+        
+    if ($self->{keeplinenums}) {
+        $info->{startline} = $properties->{TagStart};
+        $info->{endline}   = $properties->{TagEnd};
+    }
+
+    if ($self->{keepdata}) {
+        $info->{new_value} = $properties->{Attributes}->{$attr};
+    }
+    return $info;
+}
+
+sub missing_attribute {
+    my $self = shift;
+    my ($attr, $element, $new_properties, $old_properties) = @_;
+    my ($element_name, $parent) = parent_and_name($element);
+    my $info = {context  => $element,
+                message  => "Attribute '$attr' missing from element '$element_name'."};
+         
+    if ($self->{keeplinenums}) {
+        $info->{startline} = $new_properties->{TagStart};
+        $info->{endline}   = $new_properties->{TagEnd};
+    }
+
+    if ($self->{keepdata}) {
+        $info->{old_value} = $old_properties->{Attributes}->{$attr};
+    }
+    return $info;
+}
+
+sub attribute_value {
+    my $self = shift;
+    my ($attr, $element, $new_properties, $old_properties) = @_;
+    my ($element_name, $parent) = parent_and_name($element);
+    my $info = {context  => $element,
+                message  => "Attribute '$attr' has different value in element '$element_name'."};
+                  
+    if ($self->{keeplinenums}) {
+        $info->{startline} = $new_properties->{TagStart};
+        $info->{endline}   = $new_properties->{TagEnd};
+    }
+        
+    if ($self->{keepdata}) {
+        $info->{old_value} = $old_properties->{Attributes}->{$attr};
+        $info->{new_value} = $new_properties->{Attributes}->{$attr};
+    }
+    return $info;
+}
+
+sub namespace_uri {
+    my $self = shift;
+    my ($element, $new_properties, $old_properties) = @_;
+    my ($element_name, $parent) = parent_and_name($element);
+    my $info = {context  => $element,
+                message  => "Element '$element_name' within different namespace."};
+            
+    if ($self->{keeplinenums}) {
+        $info->{startline} = $new_properties->{TagStart};
+        $info->{endline}   = $new_properties->{TagEnd};
+    }
+                            
+    if ($self->{keepdata}) {
+        $info->{old_value} = $old_properties->{NamspaceURI};
+        $info->{new_value} = $new_properties->{NamspaceURI};
+    }
+    return $info;
+}
+
+sub parent_and_name {
+    my $element = shift;
+    my @steps = split('/', $element);   
+    my $element_name = pop (@steps);
+    my $parent = join '/', @steps;
+    $element_name =~ s/\[\d+\]$//;
+    return ($element_name, $parent);
+}
+
+1;
+__END__
+# Below is the stub of documentation for your module. You better edit it!
+
+=head1 NAME
+
+XML::SemanticDiff::BasicHandler - Default handler class for XML::SemanticDiff
+
+=head1 SYNOPSIS
+
+  use XML::SemanticDiff;
+  my $diff = XML::SemanticDiff->new();
+        
+  foreach my $change ($diff->compare($file, $file2)) {
+      print "$change->{message} in context $change->{context}\n";
+  }
+
+=head1 DESCRIPTION
+
+This is the default event handler for XML::SemanticDiff. It implements nothing useful apart from the parent class and should
+never be used directly.
+
+Please run perldoc XML::SemanticDiff for more information.
+
+=head1 AUTHOR
+
+Kip Hampton khampton@totalcinema.com
+
+=head1 COPYRIGHT
+                  
+Copyright (c) 2000 Kip Hampton. All rights reserved. This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+XML::SemanticDiff
+
+=cut
+

perl/modules/XML-SemanaticDiff/t/01basic.t

+use Test;
+BEGIN { plan tests => 2 }
+END { ok(0) unless $loaded }
+use XML::SemanticDiff;
+$loaded = 1;
+ok(1);
+
+my $diff = XML::SemanticDiff->new();
+ok($diff);

perl/modules/XML-SemanaticDiff/t/02load_xml.t

+use Test;
+BEGIN { plan tests => 1 }
+
+use XML::SemanticDiff;
+
+my $diff = XML::SemanticDiff->new();
+
+my $xml1 = qq*<?xml version="1.0"?>
+<root>
+<el1 el1attr="good"/>
+<el2>Some Text</el2>
+</root>
+*;
+
+my $foo = $diff->read_xml($xml1);
+
+ok($foo);

perl/modules/XML-SemanaticDiff/t/03simple_compare.t

+use Test;
+BEGIN { plan tests => 2 }
+
+use XML::SemanticDiff;
+
+$xml1 = <<'EOX';      
+<?xml version="1.0"?>
+<root>
+<el1 el1attr="good"/>
+<el2 el2attr="good">Some Text</el2>
+<el3/>
+</root>
+EOX
+
+$xml2 = <<'EOX';      
+<?xml version="1.0"?>
+<root>
+<el1 el1attr="bad"/>
+<el2 bogus="true"/>
+<el4>Rogue</el4>
+</root>
+EOX
+
+my $diff = XML::SemanticDiff->new();
+
+my @results = $diff->compare($xml1, $xml2);
+
+ok(@results == 6);
+
+@results = $diff->compare($xml1, $xml1);
+
+ok(@results == 0);

perl/modules/XML-SemanaticDiff/t/04namespaces.t

+use Test;
+BEGIN { plan tests => 4 }
+
+use XML::SemanticDiff;
+
+my $xml1 = <<'EOX';    
+<?xml version="1.0"?>
+<root xmlns="http://localhost/foo">
+<el1 el1attr="good"/>
+<el2 el2attr="good">Some Text</el2>
+<el3/>
+</root>
+EOX
+
+my $xml2 = <<'EOX';    
+<?xml version="1.0"?>
+<foo:root xmlns:foo="http://localhost/foo">
+<foo:el1 el1attr="good"/>
+<foo:el2 el2attr="good">Some Text</foo:el2>
+<foo:el3/>
+</foo:root>
+EOX
+
+my $xml3 = <<'EOX';    
+<?xml version="1.0"?>
+<root xmlns="http://localhost/foo">
+<el1 xmlns="http://localhost/bar" el1attr="good"/>
+<el2 el2attr="good">Some Text</el2>
+<el3/>
+</root>
+EOX
+
+my $diff = XML::SemanticDiff->new();
+
+my @results = $diff->compare($xml1, $xml2);
+
+ok(@results == 0);
+
+@results = $diff->compare($xml1, $xml3);
+
+ok(@results == 1);
+
+ok($results[0]->{context} eq '/root[1]/el1[1]');
+
+ok($results[0]->{message} =~ /namespace/gi);
+

perl/modules/XML-SemanaticDiff/t/05simple_handler.t

+use Test;
+BEGIN { plan tests => 1 }
+
+use XML::SemanticDiff;
+
+$xml1 = <<'EOX';      
+<?xml version="1.0"?>
+<root>
+<el1 el1attr="good"/>
+<el2 el2attr="good">Some Text</el2>
+<el3/>
+</root>
+EOX
+
+$xml2 = <<'EOX';      
+<?xml version="1.0"?>
+<root>
+<el1 el1attr="bad"/>
+<el2 bogus="true"/>
+<el4>Rogue</el4>
+</root>
+EOX
+
+my $handler = SimpleDiff->new();
+
+my $diff = XML::SemanticDiff->new(diffhandler => $handler);
+
+my @results = $diff->compare($xml1, $xml2);
+
+ok(@results == 8);
+
+package SimpleDiff;
+
+use strict;
+
+sub new {
+    my ($proto, %args) = @_;
+    my $class = ref($proto) || $proto;
+    my $self  = \%args;
+    bless ($self, $class);
+    return $self;
+}
+
+sub init {
+    return 1;
+}
+
+sub rogue_element {
+    return 1;
+}
+
+sub rogue_attribute {
+    return 1;
+}
+
+sub missing_element {
+    return 1;
+}
+
+sub missing_attribute {
+    return 1;
+}
+
+sub attribute_value {
+    return 1;
+}
+
+sub element_value {
+    return 1;
+}
+
+sub namespace_uri {
+    return 1;
+}
+
+sub final {
+   #
+   return 1;
+}
+1;
+

perl/modules/XML-SemanaticDiff/t/06pass_to_handler.t

+use Test;
+BEGIN { plan tests => 1 }
+
+use XML::SemanticDiff;
+
+$xml1 = <<'EOX';      
+<?xml version="1.0"?>
+<root>
+<el1 el1attr="good"/>
+<el2 el2attr="good">Some Text</el2>
+<el3/>
+</root>
+EOX
+
+$xml2 = <<'EOX';      
+<?xml version="1.0"?>
+<root>
+<el1 el1attr="bad"/>
+<el2 bogus="true"/>
+<el4>Rogue</el4>
+</root>
+EOX
+
+my $handler = BetterDiff->new();
+
+my $diff = XML::SemanticDiff->new(diffhandler => $handler);
+
+my @results = $diff->compare($xml1, $xml2);
+
+ok(@results == 6);
+
+package BetterDiff;
+
+use strict;
+
+sub new {
+    my ($proto, %args) = @_;
+    my $class = ref($proto) || $proto;
+    my $self  = \%args;
+    bless ($self, $class);
+    return $self;
+}
+
+sub rogue_element {
+    my $self = shift;
+    my ($element_path, $new_element) = @_;
+    return 1 if $element_path and $new_element;
+}
+
+sub rogue_attribute {
+    my $self = shift;
+    my ($attr, $element_path, $new_element, $old_element) = @_;
+    return 1 if $attr and $element_path and $new_element and $old_element;
+}
+
+sub missing_element {
+    my $self = shift;
+    my ($element_path, $old_element) = @_;
+    return 1 if $element_path and $old_element;
+}
+
+sub missing_attribute {
+    my $self = shift;
+    my ($attr, $element_path, $new_element, $old_element) = @_;
+    return 1 if $attr and $element_path and $new_element and $old_element;
+}
+
+sub attribute_value {
+    my $self = shift;
+    my ($attr, $element_path, $new_element, $old_element) = @_;
+    return 1 if $attr and $element_path and $new_element and $old_element;
+}
+
+sub element_value {
+    my $self = shift;
+    my ($element_path, $new_element, $old_element) = @_;
+    return 1 if $element_path and $new_element and $old_element;
+}
+
+sub namespace_uri {
+    return 1;
+}
+
+1;
+

perl/modules/XML-SemanaticDiff/t/07pitest.t

+use Test;
+BEGIN { plan tests => 3 }
+
+use XML::SemanticDiff;
+
+$xml1 = <<'EOX';      
+<?xml version="1.0"?>
+<?xml-stylesheet href="." type="text/xsl"?>
+<root>
+<el1 blarg="."/>
+</root>
+EOX
+
+$xml2 = <<'EOX';      
+<?xml version="1.0"?>
+<?xml-stylesheet href="." type="application/x-ubuparser" extra="bogus" ?>
+<root>
+<el1 blarg="."/>
+</root>
+EOX
+
+$xml3 = <<'EOX';      
+<?xml version="1.0"?>
+<?xml-stylesheet href="." type="text/xsl"?>
+<?xml-stylesheet href="mysheet.xsl" type="text/xsl"?>
+<root>
+<el1 blarg="."/>
+</root>
+EOX
+
+
+my $diff = XML::SemanticDiff->new();
+
+my @results = $diff->compare($xml1, $xml2);
+
+ok(@results == 2);
+
+@results = $diff->compare($xml1, $xml1);
+
+ok(@results == 0);
+
+my $full = XML::SemanticDiff->new(keepdata => 1, keeplinenums => 1);
+
+@results = $full->compare($xml1, $xml3);
+
+#foreach my $msg (@results) {
+#  warn "RES " . $msg->{startline} . "\n";
+#}
+
+ok(@results == 1);
+
+
+
+

perl/modules/XML-SemanaticDiff/t/08nonexist_ns.t

+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+
+use Test::More tests => 2;
+
+use XML::SemanticDiff;
+
+$SIG{__WARN__} = sub { die $_[0]; };
+
+my $xml1 = <<'EOX';
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE
+    html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+<head>
+<title>Create a Great Personal Home Site</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+</head>
+<body>
+<h2 id="books">Books</h2>
+<p>
+These are my books.
+</p>
+<h3 id="fiction_books">Fiction books</h3>
+
+<div class="prod">
+<div class="head">
+<p class="prod_img">
+<a href="http://www.amazon.com/exec/obidos/ASIN/06903459409/ref=nosim/shlomifishhom-20/"><img src="images/little_women.jpg" alt="Preview" /></a>
+</p>
+<p class="prod_title">
+<a href="http://www.amazon.com/exec/obidos/ASIN/06903459409/ref=nosim/shlomifishhom-20/">Little Women</a>
+</p>
+</div>
+<div class="desc">
+<p>
+Little Women by Louisa May Alcott.
+</p>
+</div>
+</div>
+
+<h3 id="computer_books">Computer books</h3>
+</body>
+</html>
+EOX
+
+my $xml2 = <<'EOX';      
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
+  <head>
+    <title>Create a Great Personal Home Site</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+  </head>
+  <body>
+    <h2 id="books">Books</h2>
+    <p>
+                    These are my books.
+                </p>
+    <h3 id="fiction_books">Fiction books</h3>
+    <div class="prod">
+      <div class="head">
+        <p class="prod_img">
+          <a href="http://www.amazon.com/exec/obidos/ASIN/06903459409/ref=nosim/shlomifishhom-20/">
+            <img alt="Preview" src="images/little_women.jpg"/>
+          </a>
+        </p>
+        <p class="prod_title">
+          <a href="http://www.amazon.com/exec/obidos/ASIN/06903459409/ref=nosim/shlomifishhom-20/">Little Women</a>
+        </p>
+      </div>
+      <div class="desc">
+        <p>
+                            Little Women by Louisa May Alcott.
+                        </p>
+      </div>
+    </div>
+    <h3 id="computer_books">Computer books</h3>
+  </body>
+</html>
+EOX
+
+my $diff = XML::SemanticDiff->new();
+
+my @results=(qw(Humpty Dumpty sat on a wall));
+eval {
+@results = $diff->compare($xml1, $xml2);
+};
+
+# TEST
+is ($@, "", "No exception was thrown");
+# TEST
+ok ((@results == 0), "XML is OK.");
+
+
+