• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

XML-Daten verarbeiten

nexus0815

New member
Hallo zusammen,
ich stecke gerade an meinem Projekt fest.
Es handelt sich hierbei um ein internes Nachrichtensystem auf meiner Internetseite.
Die Nachrichten liegen in einer MySQL-Datenbank und werden mittels AJAX abgerufen.
AJAX liefert die Kopfdaten (also Absender, Betreff usw.) als XML-Datei, welche wie folgt aussieht:
Code:
<mail>
   <mailID>1</mail>
   <mailSender>Max Muster</mailSender>
   <mailDate>16.04.2014</mailDate>
   <mailSubject>Testmail</mailSubject>
</mail>

Auf der Seite sieht meine Javascript-Funktion (der Übersichtlichkeit zuliebe ohne AJAX-Gedöns) so aus:

Code:
var $output = "";
var mails = xml.getElementsByTagName("mail");
var count = mails.length;

for (i=0;i<count;i++) {
 $output += "MailID: " + mails[i].childNodes[1].firstChild.nodeValue + "<br>";
 $output += "MailSender: " + mails[i].childNodes[2].firstChild.nodeValue + "<br>";
 $output += "MailDate: " + mails[i].childNodes[3].firstChild.nodeValue + "<br>";
 $output += "MailSubject: " + mails[i].childNodes[4].firstChild.nodeValue + "<br>";
}

Mein Problem: Die MailID wird korrekt abgerufen, danach bekomme ich den Fehler "mails.childNodes[2].firstChild is null"...

Ich habe mich durch Internet gegoogelt und diverse Ansätze probiert, allerdings ohne Erfolg.
Bin mir ziemlich sicher, dass es dafür eine einfache Lösung gibt, auf die ich nur nicht komme ;)
Muss ich die ChildNodes in einer zweiten for-schleife auslesen???

Hoffe ich habe nix vergessen...
Ich bin für jeden Denkanstoss dankbar. Vielen Dank schonmal.

Liebe Grüße
Chris
 
Ist denn das .firstChild eigentlich nötig? Bezeichnet mails.childNodes[x].nodeValue nicht auch eindeutig? Ich muss dazu sagen, dass ich sonst nichts mit XML mache, hab also keine Übung.
 
Die Nachrichten liegen in einer MySQL-Datenbank und werden mittels AJAX abgerufen.
dann lass dir die daten doch als json ausgeben, das ist wesentlich einfacher zu handhaben.

Mein Problem: Die MailID wird korrekt abgerufen, danach bekomme ich den Fehler "mails.childNodes[2].firstChild is null"...

die MailID besorgst du dir vom index 1
mails.childNodes[1].firstChild.nodeValue
vermutlich, weil auf index 0 eine textnode liegt mit "\n "
dann liegt aber auf index 2 auch eine textnode mit "\n "
darum ist es ungünstig auf die knoten so fest zuzugreifen, ohne sie prüfung
entweder nimmst du dir ein framework, mit dem du über selektoren genau auf die knoten zugreifst, die du benötigst, oder du machst das nativ oder über xpath
Code:
var mailid = mails[i].getElementsByTagName("mailId");
if (mailid.length == 1)
{
  mailid=parseInt(mailid.textContent);
}
else
{
  ...
}
 
Hab's auch schon ohne firstChild versucht, dann kommt aber die Fehlermeldung "not defined"...

@hesst: Werde ich bei Gelegenheit mal ausprobieren, danke
 
@hesst: Werde ich bei Gelegenheit mal ausprobieren, danke
Das solltest du jetzt gleich so machen, da Nodeszählen nie gescheit funktioniert (manche Browser ignorieren Textnodes mit nur Whitespaces und dann sind alle Zahlen falsch) und extrem nervig zu Warten ist.

Aber da ist ein kleiner Fehler im Code von hesst:
Code:
var mailid = mails[i].getElementsByTagName("mailId");
if (mailid.length === 1){
  mailid=parseInt(mailid[0].firstChild.nodeValue, 10);
}
else {
  ...
}
 
Zuletzt bearbeitet:
Das "===" und die Basis im parseInt() hab' ich eingebaut, da man damit einfach sicherer fährt.

über .textContent vs .firstChild.nodeValue kann man streiten - eigentlich finde ich .textContent schöner, aber es wird nicht vom IE8 unterstützt.

Aber der Fehler war "mailid" vs "mailid[0]" - mailid ist eine Collection...

EDIT: noch was zu "wie in den meisten fällen": ich bin faul, deswegen will ich mir nicht jedes mal überlegen, ob es hier nötig ist oder nicht und setzte es deswegen immer. Auch ist es schneller, da es keinen Autocast ausführen muss. Zusätzlich ist es transitiv...
 
Zuletzt bearbeitet:
ohh, gleich soviel übersehen

Das "===" und die Basis im parseInt() hab' ich eingebaut, da man damit einfach sicherer fährt.
macht es meiner meinung nach nicht sicherer

noch was zu "wie in den meisten fällen": ich bin faul, deswegen will ich mir nicht jedes mal überlegen, ob es hier nötig ist oder nicht und setzte es deswegen immer.
überlegen musst du doch sowieso, bei == ob es casts geben könnte die unerwünscht sind, bei === ob du noch weitere fälle beachten musst
und mit == fährst bist du in den meisten fällen auf der richtigen seite, === benötigt man sehr selten

Auch ist es schneller, da es keinen Autocast ausführen muss.
aber sobald == castet, musst du bei === den fall speziell behandeln
 
macht es meiner meinung nach nicht sicherer
Ja, das ist deine Meinung...
Code:
alert(parseInt("0010"));
alert(parseInt("0010", 10));
- führ' das mal im IE8 und im IE9 aus... nicht das gleiche Verhalten - willst du sowas wirklich tollerieren?

Und
Code:
alert("" == 0);
ist für mich einfach zu nervig, wenn ich solche Sachen dauernd im Hinterkopf behalten muss.


überlegen musst du doch sowieso, bei == ob es casts geben könnte die unerwünscht sind, bei === ob du noch weitere fälle beachten musst
Also ich weiß, welche Typen meine Variablen haben können. S.u.
und mit == fährst bist du in den meisten fällen auf der richtigen seite, === benötigt man sehr selten
Auch stehst du mit deiner Meinung heutzutage recht alleine da:

http://www.impressivewebs.com/why-use-triple-equals-javascipt/
http://www.jslint.com/
http://stackoverflow.com/questions/...s-operator-vs-i-use-in-javascript-comparisons

aber sobald == castet, musst du bei === den fall speziell behandeln
Sobald == castet war der Funktionsaufruf falsch oder ich habe in meiner Programmlogik irgendwas nicht bedacht. Muss man also auf jeden Fall nachbessern. Ich schreibe immer "===" und habe es noch nie bereut.

Wenn ich casten will, mache ich das explizit.

PS: Willst du wirklich sowas durchgehen lassen?
Code:
({toString: function(){return "hallo"}}) == "hallo"
 
Hallo nochmal,
habe den Code jetzt wie beschrieben abgeändert und jetzt läuft alles super...

Vielen lieben Dank nochmals und noch ein schönes Osterfest ;)
 
Ja, das ist deine Meinung...
ja

führ' das mal im IE8 und im IE9 aus... nicht das gleiche Verhalten - willst du sowas wirklich tollerieren?
selbst ich habe keinen ie8, jquery unterstützt ihn nicht mehr, xp wird in den meisten firmen ausgetauscht, den ie8 noch zu unterstützen ist genauso sinnvoll wie den ie6 noch zu unterstützen, das macht kaum noch jemand. auch hier im konkreten fall kommen keine führenden nullen vor, aber gut, das kann man so schreiben wenn man will, man macht ja nichts kaputt.

Und
Code:
alert("" == 0);
ist für mich einfach zu nervig, wenn ich solche Sachen dauernd im Hinterkopf behalten muss.
musst du trotzdem, oder wie kommst du auf die idee, dass das false liefern soll?

Also ich weiß, welche Typen meine Variablen haben können.
ok, wo ist dann das problem?

Sobald == castet war der Funktionsaufruf falsch oder ich habe in meiner Programmlogik irgendwas nicht bedacht.
und das findest du schneller, wenn du === verwendest?
ob du fehlerhaft true bekommst bei ==, oder fehlerhaft false bei === ist für die fehlersuche egal

Muss man also auf jeden Fall nachbessern.
finde ich nicht, ein
var name = input.value
if (!name)
{
alert ("kein name eingegeben")
}
ist ok

Ich schreibe immer "===" und habe es noch nie bereut.
und ich immer == und habe es auch noch nie bereut.

Willst du wirklich sowas durchgehen lassen?
Code:
({toString: function(){return "hallo"}}) == "hallo"
warum nicht? das schreit ja geradezu nach "ist so gewollt"!
 
Macht es Sinn, die Parallelunterhaltung über == und === in einen eigenen Thread zu packen? Oder gehört das noch im engeren Sinne zu "XML-Daten verarbeiten"?
 
es ist eine diskussion die in diesem thread entstanden ist, warum soll sie woanders hin?
Weil sie thematisch m.E. nicht zwingend zur Überschrift "XML-Daten verarbeiten" gehört und inhaltlich in einem separaten Thread Sinn machen würde bezüglich Auffindbarkeit und Suchmaschinen.
Korbinian, was sagst du?
 
@mikdoe: von mir aus kann das zusammen bleiben, da es nicht zwei parallele Unterhaltungen sind. Das würde extrem verwirren. Aber von mir aus kann man das auch trennen - ist mir egal.

selbst ich habe keinen ie8
Wenn du XP hast, dann hast du den IE8. Du bekommst keinen neueren installiert und deinstallieren kannst du ihn auch nicht.
, jquery unterstützt ihn nicht mehr, xp wird in den meisten firmen ausgetauscht, den ie8 noch zu unterstützen ist genauso sinnvoll wie den ie6 noch zu unterstützen, das macht kaum noch jemand.
Ich finde auch, dass der IE8 ein Wackelkandidat ist. Wenn es aber nicht zu aufwändig ist, nehme ich ihn immer noch rein.
auch hier im konkreten fall kommen keine führenden nullen vor, aber gut, das kann man so schreiben wenn man will, man macht ja nichts kaputt.
Es kann aber schnell mal passieren, dass da führende Nullen dazukommen: Daten aus einer anderen Quelle, Änderungen am Backend und das JS nicht im Hinterkopf... ich bin faul! Deswegen schreibe ich das immer so, dann muss ich mir nichts merken... und, wie du gesagt hast, man macht damit nichts kaputt - also nur Vorteile bei ein bisschen mehr Aufwand. Für mich ein klarer Fall.

musst du trotzdem, oder wie kommst du auf die idee, dass das false liefern soll?
Nö, muss ich nicht, wenn ich === verwende...
Wie kommst du auf die Idee, dass das true liefern soll?

ok, wo ist dann das problem?
Ich hab' kein Problem, da ich === verwende.

und das findest du schneller, wenn du === verwendest?
ob du fehlerhaft true bekommst bei ==, oder fehlerhaft false bei === ist für die fehlersuche egal
Wenn ein Fehler da ist, macht das keinen Unterschied. Mit === kommen nur einfach weniger Fehler vor.

Äh... wenn sich mein Programm nicht so verhält, wie ich das gerne hätte, muss ich nachbessern.

, ein
var name = input.value
if (!name)
{
alert ("kein name eingegeben")
}
ist ok
Ja, das ist OK. Aber darum geht es gerade auch gar nicht. Das ist die Unterscheidung, ob ein Wert falsy oder truthy ist. Das ist auch eindeutig und logisch. So wird " \n\t\r" als truthy interpretiert...

warum nicht? das schreit ja geradezu nach "ist so gewollt"!
Klar, wenn das genau so dasteht.
Aber wenn du eine Funktion schreibst, die du vielleicht noch ein paar mal verwenden willst (eventuell auch noch Monate/Jahre später), und du vergleichst da irgendeinen Parameter mit irgendeinem String in einem if. Jetzt nimmst du im if an, dass der Parameter ein String ist und machst irgendwas Stringspezifisches - schon hast du einen Fehler.
 
Zurück
Oben