Öttinger
(Themenstarter)
Anmeldungsdatum: 28. Januar 2009
Beiträge: 504
|
Zeile 43! Ich hatte darüber auch nen Kommentar geschrieben 😉
Das meinte ich nicht, ich meinte das du das selbst geschreiben hast und keine fertige Funktion dafür verwendest. Ich ging davon aus das die Logik hinter dem mapping nur benannt werden braucht und dann zur Verfügung steht ähnlich dem Mechanismus des deklarierens.
Das kapiere ich jetzt wiederum nicht!
Hier versthe ich nicht welchen Teil du nicht verstehst.
Was sollte diese hypotetische Funktion denn als Datentypen zurückliefern? Ein "Node"-Objekt? Was wäre damit großartig gewonnen?
Ganz einfach man könnte sich die suche nach den Referenzen sparen, diese Beziehung wäre bereits gegeben.
Ich kapiere wirklich nicht, wieso Du hier so zynisch wirst
Das geht mir auch manchmal so.
Da hilft auch kein Sarkasmus - ich bin nicht schuld daran, dass es das, was Du vermeindlich suchst, nicht gibt. Ich habe Dir lediglich versucht klar zu machen, *wieso* es das nicht gibt und *dass* Du eigentlich ein ganz anderes Problem lösen willst 😉
Ja das hatte ich dann falsch verstanden, mir war nicht von Anfang an klar das es sowas nicht gibt. Für mich klang es so das der Parser das können sollte. In R habe ich das bespw. jetzt so geschreiben, das die Attribute der referenzierten Objekte in die Knoten geschrieben werden, so dass ich die dann entsprechend Objekte davon erstelle: diese Lösung kann gerne noch verbessert werden, bspw. muss der loop raus und die Objekte müssen als ganzes ersetzt werden. Das Überführen in die Interne-Struktur findet dann in einer separaten Methode statt die hier nicht aufgeführt ist. 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
36
37
38
39 | txt = "<doc>
<part id=\"id\" name=\"name\">
<elem idref=\"1\">
<fac idref=\"1\"/>
<fac idref=\"1\"/>
</elem>
<elem idref=\"2\">
<fac idref=\"1\"/>
<fac idref=\"2\"/>
</elem>
</part>
<elems>
<elem id=\"1\" name=\"name\"/>
<elem id=\"2\" name=\"name\"/>
</elems>
<facs>
<fac id=\"1\" name=\"name\"/>
<fac id=\"2\" name=\"name\"/>
</facs>
</doc>"
doc <- xmlTreeParse(txt, useInternalNodes = TRUE)
list.prc <- getNodeSet(doc, "//part")
list.refs<-c(elem=xpathSApply(doc, "//elems"),fac=xpathSApply(doc, "//facs"))
lookupRefNode(list.prc,list.refs)
lookupRefNode<-function(list.node,list.refs){
for(node in list.node){
if(!is.na(attrRef<-xmlAttrs(node)["idref"])){
name<-xmlName(node)
nodeRef<-xpathSApply(list.refs[[name]], paste("./",name,"[@id='",attrRef,"']",sep=""))
xmlAttrs(node)<-xmlAttrs(nodeRef[[1]])
}
if(length(children<-xmlChildren(node))>0)
xmlChildren(node)<-lookupRefNode(children,list.refs)
}
return(list.node)
}
|
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Öttinger schrieb: Was sollte diese hypotetische Funktion denn als Datentypen zurückliefern? Ein "Node"-Objekt? Was wäre damit großartig gewonnen?
Ganz einfach man könnte sich die suche nach den Referenzen sparen, diese Beziehung wäre bereits gegeben.
Die Frage ist nur, will man das auch? Du bedenkst glaube ich nicht, dass einer solchen Referenz idR. eine 1:n oder gar n:m-Beziehung zu Grunde liegt. Und wenn man an der Stelle einfach die stumpfen Nodes vom Parser präsentiert bekäme, dann würdest Du zig mal *dasselbe* Objekt in Deiner Domänen-Ebene generieren, obwohl es nur *einmal* notwendig wäre. In meinem Python-Beispiel zeige ich ja gerade, dass gleiche Element-Objekte in verschiedenen Conatinern Verwendung finden können. Dein Gedankenspiel hilft also nur, wenn tatsächlich zu jeder Referenz nur *ein* Eintrag mit "Datenwerten" existierte - dann wäre die XML-Struktur aber für den *****, da man dann keine Referenzierung bräuchte, sondern die Datenwerte *direkt* an dieser Stelle im XML-Baum schreiben sollte. Auch wenn ich kein R kann, so verstehe ich doch im groben, was Du da tust und das ist sicherlich suboptimal. Du manipulierst das XML - wozu? Das kostet doppelt so viel Arbeit! Du musst ja erst einmal die Datenknoten finden und die referenzierenden Knoten damit ersetzen. Erst anschließend baust Du ja wohl (hier nicht gezeigt) Deine interne Reüräsentation damit auf. Zimelich umständlich und - wie zuvor beschrieben - auch suboptimal bezüglich des Speicherverbrauchs.
|
Öttinger
(Themenstarter)
Anmeldungsdatum: 28. Januar 2009
Beiträge: 504
|
Die Frage ist nur, will man das auch? Du bedenkst glaube ich nicht, dass einer solchen Referenz idR. eine 1:n oder gar n:m-Beziehung zu Grunde liegt. Und wenn man an der Stelle einfach die stumpfen Nodes vom Parser präsentiert bekäme, dann würdest Du zig mal *dasselbe* Objekt in Deiner Domänen-Ebene generieren, obwohl es nur *einmal* notwendig wäre. In meinem Python-Beispiel zeige ich ja gerade, dass gleiche Element-Objekte in verschiedenen Conatinern Verwendung finden können.
Du meinst wenn du ein Element Objekt an verschiedene stellen der part Liste kopierst(?), dann ja, falls es keine Kopie ist. Was passiert wenn gleiche Instanzen (Objekte) der Klasse Element an verschiedene Objekte einer Klasse "Part" übergeben werden und da einer Klassenvariable zugewiesen werden? Was passiert in Folge einer Änderung dieser Variablen an einem bel. "Part" Objekt? Dann hat das keine Auswirkungen auf die restlichen Objekte vom Typ "Part", weil das im Kontext des Erzeugens von Objekten eine echte Kopie ist und das würde die Sache schon ganz anders aussehen lassen. Wie würdest du die gleiche Rerfernzstruktur intern dann abbilden wollen, das hast du nicht gezeigt, denn ob beim Erstellen deiner part Liste lediglich ein Zeiger auf das entsprechende Element gespeichert wird geht aus deinem Beispiel nicht hervor. Falls das überhaupt so ist, was ich mir kaum vorstellen kann, da Phyton eine moderne objektorientierte Sprache und es vermutlich keine hieraischen Untershciede zwischen den Datentypen wie einer Liste und Objekten vom Typ Element macht. Wie lesen, ersetzen und schreiben im Detail an Rechenleistung und Speicher nimmt war nicht meine Frage. Als man mir das mit den refernezen erzählte klang es so als wenn das der Funktionsumfang des Parsers liefern müsse, obwohl ich da noch einmal nachhackte weil ich es mir eben auch nicht vorstellen konnte. Ist auf jeden Fall gut das ich weiß das es sowas nicht gibt, wie auch da müsste eben eine extra Beschreibung der Logik her ähnlich den XSD Files die sagt dem Parser ja auch wie er das XML bzgl. der Inhalte Prüfen soll, deshalb dachte ich in diese Richtung.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Öttinger schrieb: Du meinst wenn du ein Element Objekt an verschiedene stellen der part Liste kopierst(?), dann ja, falls es keine Kopie ist.
Statt "kopieren" nimm hinzufügen; ja, das meine ich.
Was passiert wenn gleiche Instanzen (Objekte) der Klasse Element an verschiedene Objekte einer Klasse "Part" übergeben werden und da einer Klassenvariable zugewiesen werden? Was passiert in Folge einer Änderung dieser Variablen an einem bel. "Part" Objekt?
Da es sich bei dem Element-Objekt um dasselbe Objekt handelt, änderst Du dieses. Die Referenzen von verschiedenen Part-Objekten auf dasselbe Element-Objekt ändert sich ja nicht, daher wären diese Änderungen natürlich auch dort "verfügbar".
Dann hat das keine Auswirkungen auf die restlichen Objekte vom Typ "Part", weil das im Kontext des Erzeugens von Objekten eine echte Kopie ist und das würde die Sache schon ganz anders aussehen lassen.
Du meinst, wenn man für jede Referenz ein eigenständiges Element-Objekt innerhalb eines Part-Containers anlegte? Das widerspricht aber der Semantik der XML-Struktur; wenn ein Element-Objekt ein reines Value-Objekt sein soll, darf es eigentlich *keine* Identität haben und somit auch nicht referenzierbar sein 😉
Wie würdest du die gleiche Rerfernzstruktur intern dann abbilden wollen, das hast du nicht gezeigt, denn ob beim Erstellen deiner part Liste lediglich ein Zeiger auf das entsprechende Element gespeichert wird geht aus deinem Beispiel nicht hervor.
Doch. Es ist halt nur Python-Semantik 😉 Das Element mit dem Key "b" ist in beiden Part-Listen *dasselbe* Objekt. Hier mal eine Analyse auf dem parts -Dictionary:
1
2
3
4
5
6
7
8
9
10
11
12
13 | for key, part in parts.items():
print(key)
for element in part:
print(element, id(element))
>
simples Teil
Element b: def 68601616 # ← beachte die Id!
Element c: ghi 68601784 # ← und hier auch
komplexes Teil
Element a: abc 68601560
Element b: def 68601616 # ← es ist dasselbe Objekt wie oben!
Element c: ghi 68601784 # ← und dieses auch
|
Das Ergebnis ist ja auch logisch; die Elemente "b" und "c" sind ja nur *einmal* erstellt worden (get_elements ). Wie ich schon schrieb erfolgt die Zuweisung in die Part-Mengen in Zeile 43 aus den erstellten Element-Objekten. Man kann nun auch "b"-Objekte ändern:
| parts["simples Teil"][0].name = "foo"
# Ausgabe wie oben:
>
simples Teil
Element b: foo 68601616 # ← heißt jetzt foo
Element c: ghi 68601784
komplexes Teil
Element a: abc 68601560
Element b: foo 68601616 # ← und hier natürlich auch
Element c: ghi 68601784
|
Hätte ich durch eine Ummodelung des XML - wie bei Dir - oder eine Parser-Funktionalität direkt innerhalb des Part-Subbaumes jeweils die Element-Knoten vorliegen und "naiv" einfach daraus immer ein Element-Objekt erstellt, wären es zwei unterschiedliche Objekte "b" und "c" geworden.
Falls das überhaupt so ist, was ich mir kaum vorstellen kann, da Phyton eine moderne objektorientierte Sprache und es vermutlich keine hieraischen Untershciede zwischen den Datentypen wie einer Liste und Objekten vom Typ Element macht.
Die Aussage verstehe ich nicht!
Wie lesen, ersetzen und schreiben im Detail an Rechenleistung und Speicher nimmt war nicht meine Frage.
Ja und? Deswegen darf ich Dich diesbezüglich nicht aufklären, oder was? 😲
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13213
|
Öttinger schrieb:
Wie lesen, ersetzen und schreiben im Detail an Rechenleistung und Speicher nimmt war nicht meine Frage. Als man mir das mit den refernezen erzählte klang es so als wenn das der Funktionsumfang des Parsers liefern müsse, obwohl ich da noch einmal nachhackte weil ich es mir eben auch nicht vorstellen konnte. Ist auf jeden Fall gut das ich weiß das es sowas nicht gibt, wie auch da müsste eben eine extra Beschreibung der Logik her ähnlich den XSD Files die sagt dem Parser ja auch wie er das XML bzgl. der Inhalte Prüfen soll, deshalb dachte ich in diese Richtung.
Es gibt einen Unterschied zwischen XSD und dem, was Du suchst (soweit ich das korrekt verstanden habe): die Informationen in einer XSD beziehen sich rein auf den XML-Inhalt und definieren syntaktische Regeln, mit denen man ein XML-Dokument syntaktisch validieren kann. Du sprichst aber über Informationen über die Abbildung der XML-Struktur in eine wie auch immer geartete Datenstruktur einer Programmiersprache. In vielen Sprachen gibt es dafür eigene Mechanismen, z.B. in Java JAXB. Falls es so etwas für R nicht gibt, ist die effizienteste Möglichkeit üblicherweise einen Pull- oder Push-Parser zu verwenden, weil der kein DOM baut. Man muss dann seine Datenstrukturen selber während des Parsens aufbauen. Ciao robert
|
Öttinger
(Themenstarter)
Anmeldungsdatum: 28. Januar 2009
Beiträge: 504
|
Lysander schrieb:
Ja und? Deswegen darf ich Dich diesbezüglich nicht aufklären, oder was? 😲
Doch das sollst du. Aber ersteinmal auf die Frage mit Ja, Nein oder Weiß nicht eingehen bevor ich mich durch Gegenfragen verzettel.
Doch. Es ist halt nur Python-Semantik 😉 Das Element mit dem Key "b" ist in beiden Part-Listen *dasselbe* Objekt.
Ja stimmt, da habe ich mich geirrt, nur durch diesen Mechanismus ist man ja in der Lage seine eigene Liste zu programmieren. Ich zeige dir jetzt mal R code, wo dieser Mechanismus nicht funktioniert. Den Code kannst du bestimmt auch lesen zumindest geht es mir mit deinem Phyton so und ich konnte bisher auch kein HalloWelt in Phyton A<-setClass(Class = "A",
slots = c(name = "character"
)
)
B<-setClass(Class = "B",
slots = c(name = "A"
)
)
a<-A(name="abc")
b<-B(name=a)
c<-B(name=a)
b@name@name="ABC"
b@name@name==c@name@name
b
An object of class "B"
Slot "name":
An object of class "A"
Slot "name":
[1] "ABC"
c
An object of class "B"
Slot "name":
An object of class "A"
Slot "name":
[1] "abc"
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Ich verstehe zwar die letzte Anweisung (ein Vergleich?) nicht und wieso es zu dieser Ausgabe kommt (ist das das Ergebnis vom "=="?), aber ja, hier scheint R bei der Zuweisung des name -Slots mit einem Objekt dieses zu kopieren. Interessant wäre nun, was in a nach der Änderung des name -Attributs steht. Logischer Weise sollte dort dann auch noch "abc" drin stehen. Unabhängig von verschiedener sprachlicher Semantik (auch in R dürfte man wohl Referenzen in irgend einer Form realisieren können) sehe ich aufgrund der XML-Struktur die Element-Objekte als Entitäten an. Ergo müssen diese eindeutig sein und nicht verschiedene Objekte mit der selben ID existieren. Genau das ist einfacher zu lösen, wenn man zuerst die "Referenz"-Objekte erstellt und diese anschließend in Container einsetzt, die eine "Referenzierung" auf diese Elemente vornehmen.
|
Öttinger
(Themenstarter)
Anmeldungsdatum: 28. Januar 2009
Beiträge: 504
|
Interessant wäre nun, was in a nach der Änderung des name-Attributs steht. Logischer Weise sollte dort dann auch noch "abc" drin stehen.
Ganz wie du vermutet hast steht dort "abc".
Unabhängig von verschiedener sprachlicher Semantik (auch in R dürfte man wohl Referenzen in irgend einer Form realisieren können) sehe ich aufgrund der XML-Struktur die Element-Objekte als Entitäten an. Ergo müssen diese eindeutig sein und nicht verschiedene Objekte mit der selben ID existieren. Genau das ist einfacher zu lösen, wenn man zuerst die "Referenz"-Objekte erstellt und diese anschließend in Container einsetzt, die eine "Referenzierung" auf diese Elemente vornehmen.
Kann ich nur zustimmen. Ich glaube ich habe jetzt ein genaueres Bild und kann das ersteinmal grob umsetzen, besten Dank.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Öttinger schrieb: Kann ich nur zustimmen. Ich glaube ich habe jetzt ein genaueres Bild und kann das ersteinmal grob umsetzen, besten Dank.
Gerne ☺ Mich würde allerdings brennend interessieren, wie man in R Referenzen auf Objekte übergibt... das muss doch irgend wie gehen, oder etwa nicht?
|
Öttinger
(Themenstarter)
Anmeldungsdatum: 28. Januar 2009
Beiträge: 504
|
Es gibt verschiedene Wege die bequemste ist vermutlich wenn man keine S4 Klassen sondern Refenrence Klassen verwendet. Für S4 Klassen könnte es wie folgt aussehen B<-setClass("B", slot=c(env="environment"))
setMethod("initialize", "B", function(.Object, value, ...) {
env <- new.env(parent=emptyenv())
env$value <- value
callNextMethod(.Object, env=env, ...)
})
A<-setClass(Class="A", slot=c(var="B"))
a<-B(value="a")
b<-A(var=a)
c<-A(var=a)
c@var@env$value
a@env$value="b"
b@var@env$value Allerdigns sehe ich nicht wie ich dann slots ohne entscheidungsregeln händeln würde und wie man einen optischen Bezug dieser Syntax zur "Klassenvariable" value aufbaut, welche Sie im eigentlichen Sinne darstellen soll.
|
snafu1
Anmeldungsdatum: 5. September 2007
Beiträge: 2133
Wohnort: Gelsenkirchen
|
Auf Shell-Ebene könnte man auch xmlstarlet benutzen. Aber die Shell ist hier wahrscheinlich nicht gefragt, oder?
|