Recent Changes - Search:

Accueil

OpenSSL

SyncML

Apache Portable Runtime

Libxml2

Net-snmp

CUrl

Boost

Perl

ZLib

Samba

VPN

Serveurs de messagerie

edit

PERL/XMLParser


L'objectif de ce code est le parcours d'un arbre principal pour y détecter un noeud particulier et le mettre à jour avec de nouvelles données XML.

Dans cette exemple l'arborescence d'origine ($xp) est lue jusqu'à ce que la pseudo ligne <Domain Name="DOIN7L9R"><Application Name="CAC07015108"> soit détectée.
Le noeud détecté est alors fusionné avec le nouveau noeud ($insert) de la façon suivante :

  • si les étiquettes (ici <Domain>) sont identiques, les attributs sont ajoutés ou mis à jour sur la base des nouvelles valeurs.
  • si l'étiquette est différente, la nouvelle étiquette est ajoutée après (insertAfter) l'étiquette courante.
  • si l'étiquette ajoutée contient des fils (getChildNodes != null), ses fils sont ajoutés (appendChild) au noeud courant.


#!/usr/bin/perl -w
#

use XML::XPath::XMLParser;
use XML::XPath::Node ':node_keys';

$xp = XML::XPath::XMLParser->new(xml=> "<Domain Name=\"DOIN7L9R\"><Application Name=\"CAC07015108\"><EJBComponent Name=\"servicecache-ejb-1.3.0.jar\" /><WebAppComponent Name=\"/CAC01000004/servicecache\" /></Application><Application Name=\"CAC07015100\"><EJBComponent Name=\"servicecache-ejb-1.3.0.jar\" /><WebAppComponent Name=\"/CAC07015100/servicecache\" /></Application></Domain>");
$insert=XML::XPath::XMLParser->new(xml=> "<Application Name=\"CAC07015108\" Name3=\"ff\" Name2=\"ff\"><test/></Application>");
my $root = $xp->parse;
$i=0;

print "#####avant\n";
Show($root,0);
print "\n#####fusion avec\n";
Show($insert->parse,0);

print "\n#####fusion ...\n";
Walk($root,"");
print "\n#####apres\n";
Show($root,0);

# affichage du contenu XML
sub Show{
        my $root = shift;
        my $level = shift;

        foreach $child ($root->getChildNodes){
                for (my $a=0;$a<$level;$a++){print "   ";}
                print "<".$child->getName;
                foreach $attrib ($child->getAttributeNodes){
                        print $attrib->toString;
                }
                print ">\n";

                Show($child,$level+1);

                for ($a=0;$a<$level;$a++){print "   ";}
                print "</".$child->getName.">\n";
        }
}

#Parcours de l'arborescence XML
sub Walk {
        my $root = shift;
        my $XMLParentString = shift;

        foreach $node ($root->getChildNodes){
                if ($node->getNodeType == ELEMENT_NODE()){
                        $XMLString = $XMLParentString . GetTextNode($node);

                        # test de $XMLString
                        print $XMLString."\n";

                        # l'événement recherché est trouvé
                        if($XMLString eq "<Domain Name=\"DOIN7L9R\"><Application Name=\"CAC07015108\">"){

                                $newnodes=($insert)->parse;

                                # L'arborescence XML ne peut avoir qu'une seule racine donc un seul fils
                                $newnode = $newnodes->getChildNode(1);

                                if ($newnode->getName ne $node->getName){
                                        $root->insertAfter($newnodes, $node);
                                }
                                else{
                                        #
                                        # Fusion des attributs du node courant avec le nouveau
                                        #

                                        $isNew = 0;
                                        $isMod = 0;

                                        foreach $newattrib ($newnode->getAttributes){
                                                $Traitement=0;
                                                foreach $attrib ($node->getAttributes){
                                                        if($attrib->getName eq $newattrib->getName){
                                                                $Traitement = 1;
                                                                if($attrib->getNodeValue ne $newattrib->getNodeValue){
                                                                        $attrib->setNodeValue($newattrib->getNodeValue);
                                                                }
                                                        }
                                                }
                                                if( not $Traitement){
                                                        $attrib=XML::XPath::Node::Attribute->new($newattrib->getName,$newattrib->getNodeValue);
                                                        $node->appendAttribute($attrib);
                                                }
                                        }
                                        #
                                        # ajout des fils du nouveau node au node courant
                                        #
                                        foreach $childnode ($newnode->getChildNodes){
                                                $node->appendChild ( $childnode );
                                        }
                                }
                        }
                        Walk($node,$XMLString);
                }              
        }

}


# Fonction permettant d'afficher le node courant précédé tous ses pères
sub GetTextNode {
        my $node = shift(@_);
        my $result="<".$node->getName;
        sub backwards { $a->getName cmp $b->getName; }
        my @Attributes = sort backwards $node->getAttributes;
        foreach my $attrib (@Attributes){
                $result=$result." ".$attrib->getName."=\"".$attrib->getNodeValue."\"";
        }
        $result=$result.">";
        return $result;
}

Donnera cette sortie

#####avant
<Domain Name="DOIN7L9R">
   <Application Name="CAC07015108">
      <EJBComponent Name="servicecache-ejb-1.3.0.jar">
      </EJBComponent>
      <WebAppComponent Name="/CAC01000004/servicecache">
      </WebAppComponent>
   </Application>
   <Application Name="CAC07015100">
      <EJBComponent Name="servicecache-ejb-1.3.0.jar">
      </EJBComponent>
      <WebAppComponent Name="/CAC07015100/servicecache">
      </WebAppComponent>
   </Application>
</Domain>

#####fusion avec
<Application Name="CAC07015108" Name3="ff" Name2="ff">
   <test>
   </test>
</Application>

#####fusion ...
<Domain Name="DOIN7L9R">
<Domain Name="DOIN7L9R"><Application Name="CAC07015108">
<Domain Name="DOIN7L9R"><Application Name="CAC07015108"><EJBComponent Name="servicecache-ejb-1.3.0.jar">
<Domain Name="DOIN7L9R"><Application Name="CAC07015108"><WebAppComponent Name="/CAC01000004/servicecache">
<Domain Name="DOIN7L9R"><Application Name="CAC07015108"><test>
<Domain Name="DOIN7L9R"><Application Name="CAC07015100">
<Domain Name="DOIN7L9R"><Application Name="CAC07015100"><EJBComponent Name="servicecache-ejb-1.3.0.jar">
<Domain Name="DOIN7L9R"><Application Name="CAC07015100"><WebAppComponent Name="/CAC07015100/servicecache">

#####apres
<Domain Name="DOIN7L9R">
   <Application Name="CAC07015108" Name3="ff" Name2="ff">
      <EJBComponent Name="servicecache-ejb-1.3.0.jar">
      </EJBComponent>
      <WebAppComponent Name="/CAC01000004/servicecache">
      </WebAppComponent>
      <test>
      </test>
   </Application>
   <Application Name="CAC07015100">
      <EJBComponent Name="servicecache-ejb-1.3.0.jar">
      </EJBComponent>
      <WebAppComponent Name="/CAC07015100/servicecache">
      </WebAppComponent>
   </Application>
</Domain>
Edit - History - Print - Recent Changes - Search
Page last modified on June 04, 2007, at 11:52 AM