Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]8853[/thread]

XML::DOM / XML::Semanticdiff: why oh why don't they DWIM

Leser: 2


<< |< 1 2 >| >> 13 Einträge, 2 Seiten
dukeofnukem
 2007-03-20 13:58
#75154 #75154
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
Alohá!

Bin grade dabei einen XML-Differ zu bauen der ein wenig konfigurierbare Logik enthalten soll um deltas zwischen Referenzen und Ergebnissen ausblenden zu können wenn diese erwartet und ok sind.

Aber ins Detail:

Problem 1:
Wenn ich zwei XMLs durch XML::SemanticDiff jage, erhalte ich ein array von hashrefs auf die deltas; ein hash sieht etwa so aus (Data::Dumper):
Code: (dl )
1
2
3
4
5
6
$VAR1 = {
'new_value' =>,
'context' => ,
'old_value' => ,
'message' =>
};


Hier ist lediglich interessant: In 'context' steht der Pfad in XPath-Notation.

Wenn ich jetzt versuche an den Wert der Node zu gelangen:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
sub analyze_delta {
my ($self, %args) = @_;

use XML::DOM;
use XML::DOM::XPath;

$self->{'majorDOMus'} = XML::DOM::Parser->new()
unless $self->{'majorDOMus'};

my $id = $args{'id'};

my ($tree1, $tree2) = map { $self->{'majorDOMus'}->parse($_); } ${ $self->{'failures'}->{$id}->{'doc1'} }, ${ $self->{'failures'}->{$id}->{'doc2'} };

for my $delta ( @{ $self->{'failures'}->{$id}->{'deltas'} } ) {
my $path = $delta->{'context'};
my @nodes;
( @nodes = $tree1->findnodes($path) ) ?
1 :
( @nodes = $tree2->findnodes($path) ) ?

1 :

print "\nThere is no node at '$path'\n";

print "\n", $_->getData for @nodes;

print "\n", $_->toString, "\n" for @nodes;

}
}

habe ich folgende Ausgabe bzgl. des 'getData':
Code: (dl )
Can't locate object method "getData" via package "XML::DOM::Element" at ../XmlDiffer.pm line 126.


Das war Problem 1...

Problem 2: ist die Tatsache, daß XML::SemanticDiff buggy zu sein scheint; es liefert mir teilweise einen Pfad der mit .../element[2] endet obwohl es dort nur ein Element gibt; entsprechend findet meine sub kein solches Element im Tree.

Problem 3: liegt wiederum bei XML::SemanticDiff. Beim diffen einiger XMLs wirft er mir warnings bzgl.
Code: (dl )
Use of uninitialized value in string eq at /users/user4/usr/lib/perl5/site_perl/XML/SemanticDiff.pm

die auf die SemanticDiff-internen Vergleiche verweisen:
Code: (dl )
$from_doc->{$element}->{NamespaceURI} eq $to_doc->{$element}->{NamespaceURI}
sowie
Code: (dl )
$from_doc->{$element}->{TextChecksum} eq $to_doc->{$element}->{TextChecksum}


Bzlg. Problem 2 und 3 werde ich mich wohl mal an den Author wenden; aber was mache ich bloß falsch bzlg. Problem 1?
Die Doku bzgl. XML::DOM (bzw. die spec vom DOM Class Interface) lassen mich eigentlich nur auf 'getData' schließen...

TIA,

Martin\n\n

<!--EDIT|dukeofnukem|1174392042-->
drum&bass is a state of mind
renee
 2007-03-20 14:06
#75155 #75155
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Zu 1: Du musst Dir auch die richtige Doku anschauen ;) http://search.cpan.org/dist/XML-DOM/lib/XML/DOM/Element.pod
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
dukeofnukem
 2007-03-20 14:22
#75156 #75156
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
zu 3 habe ich glaube ich was gefunden: http://rt.cpan.org/Ticket/Display.html?id=18491

zu 1: THX, will RTFM :blush:
drum&bass is a state of mind
dukeofnukem
 2007-03-20 15:52
#75157 #75157
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
FYI: Das unter obiger URL zu findende Patch fixed Probleme 2 und 3.

Wieso das allerdings nicht in ein release 0.96 getriggert oder den bug auf closed befördert hat obwohl es sich IMHO um einen gravierenden bugfix gehandelt ist mir allerdings schleierhaft. :rock:
drum&bass is a state of mind
renee
 2007-03-20 16:16
#75158 #75158
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Vielleicht weil der Autor auf nichts mehr reagiert...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
dukeofnukem
 2007-03-20 16:31
#75159 #75159
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
Tjo, hab ihm noch mal ne Mail geschrieben... *soifz*

But now for something completely different:

Wenn ich in obiger sub analyze_delta
Code: (dl )
1
2
print "\nNODEVALUE: ", $_->XML::DOM::CharacterData::getData for @nodes;
print "\nTOSTRING: ", $_->toString, "\n" for @nodes;
aufrufe, kriege ich als Ausgabe
Code: (dl )
1
2
NODEVALUE: modificationType
TOSTRING: <modificationType>NoChange</modificationType>
- wieder den Namen der Node :angry:

Dabei wird allerortens (z.B. unter http://forum.de.selfhtml.org/archiv/2000/6/t15381/) behauptet, daß ich mit
Code: (dl )
$node->getData
den Inhalt der Node bekommen sollte (oder wie nennt man den Kram zwischen den tags?), das klappt ja schon mal gar nicht...
Code: (dl )
Can't locate object method "getData" via package "XML::DOM::Element" at ../XmlDiffer.pm line 129.
Ist ja auch kein Wunder, schließlich gibt es die Methode in XML::DOM::Element gar nicht, da sind nur Methoden drin die sich mit Tags und Attributen auseinandersetzen...

Wo krieg ich denn bloß eine Methode her die mir den INHALT einer Node liefert?:rock:
XML::DOM::CharacterData sowie XML::DOM::Text haben auch nichts entsprechendes (außer eben getData) zu bieten

Danke für die Geduld mit einem n00b :p

Martin\n\n

<!--EDIT|dukeofnukem|1174401367-->
drum&bass is a state of mind
dukeofnukem
 2007-03-20 16:58
#75160 #75160
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
hmm, erase and rewind...

an sich sollte mir
Code: (dl )
print "\nNODEVALUE: ", $_->getNodeValue for @nodes;
etwas mehr liefern als
Code: (dl )
1
2
Use of uninitialized value in print at ../XmlDiffer.pm line 129.
NODEVALUE:
oder?

Laut O'Reilly's "Perl and XML, Chapter 7, XML::DOM" tut es das jedenfalls; es liefert in einem Anwendungsbeispiel tatsächlich Text, den Inhalt der Node...

*soifz*
drum&bass is a state of mind
renee
 2007-03-20 18:26
#75161 #75161
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Dann poste doch mal ein Minimalskript und eine Beispieleingabe, bei der etwas schiefläuft.
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
dukeofnukem
 2007-03-21 12:09
#75162 #75162
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
Ok, here we go; hoffe es ist minimal genug *hüstel*

Zuerst der Input, hier sei nur ein Dokument vollständig genannt, das zweite enthält statt der city 'Meatball' die city 'Arglbargl':
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0"?>
<spam-document version="3.5" timestamp="2002-05-13 15:33:45">
<!-- Autogenerated by WarbleSoft Spam Version 3.5 -->
<customer>
<first-name>Joe</first-name>
<surname>Wrigley</surname>
<address>
<street>17 Beable Ave.</street>
<city>Meatball</city>
<state>MI</state>
<zip>82649</zip>
</address>
<email>joewrigley@jmac.org</email>
<age>42</age>
</customer>
</spam-document>

nun das diffscript:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env perl

use strict;
use warnings;
use XML::DOM;
use XML::DOM::XPath;
use XML::SemanticDiff;

my ($file1, $file2) = @ARGV;

my $doc1 = do { local(*ARGV, $/, $_); @ARGV = $file1; <>; };
my $doc2 = do { local(*ARGV, $/, $_); @ARGV = $file2; <>; };

my $differ = XML::SemanticDiff->new(keepdata => 1,);
my @deltas = $differ->compare( $doc1, $doc2 );

my $majorDOMus = XML::DOM::Parser->new();
my ($tree1, $tree2) = map { $majorDOMus->parse($_); } $doc1, $doc2;

for my $delta (@deltas) {
my $path = $delta->{'context'};
my @nodes;

( push @nodes, $tree1->findnodes($path) ) ?
1 :
( push @nodes, $tree2->findnodes($path) ) ?
1 :
print "\nThere is no node at '$path'\n";

if (@nodes) {
print "\nNODEVALUE(getNodeValue): ", $_->getNodeValue for @nodes;
print "\nNODEVALUE(getData): ", $_->XML::DOM::CharacterData::getData for @nodes;
print "\nTOSTRING: ", $_->toString, "\n" for @nodes;
}
}

und die dazugehörige Ausgabe:
Code: (dl )
1
2
3
4
Use of uninitialized value in print at ./TestGetValue line 31.
NODEVALUE(getNodeValue):
NODEVALUE(getData): city
TOSTRING: <city>Meatball</city>


Hoffe das ist nicht zu unübersichtlich...

Wieso liefert getNodeValue uninitialized?

Wieso liefert XML::DOM::CharacterData::getData das Tag statt des Inhalts?

TIA,

Martin\n\n

<!--EDIT|dukeofnukem|1174471995-->
drum&bass is a state of mind
dukeofnukem
 2007-03-22 15:26
#75163 #75163
User since
2007-01-15
47 Artikel
BenutzerIn
[default_avatar]
*BUMP*

+

Hat jemand eine Idee wie ich mit XML::DOM (das ja nur DOM1 kann) Funktionalitäten aus DOM2 (insbesondere importNode()) nutzen kann (z.B. per Modul á lá XML::DOM::XPath)?

Oder einen Tip für ein reines Perl-Modul das DOM2 spricht?

Leider ist das gnome lixml2 auf den Maschinen hoffnungslos überaltert, was die Nutzung von XML::LibXML verhindert.
Das compilen gegen eigene libxml2-libs würde zwar funktionieren, da ich aber nicht auf alle Maschinen meine eigenen libs deployen kann dann auch wieder nicht.

Achja, mein ursprüngliches Problem (Auslesen des Werts einer TextNode) hat (für mich zumindest) Priorität :-)


TIA for @input

Martin
drum&bass is a state of mind
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2007-03-20 13:58.