Sziasztok!
Olyan problémám lenne, hogy xpath-al nem tudok feldolgozni olyan xml-t amiben van teg. Null pointer hibával kilép. Lenne valakinek tippje, hogyan lehetne mondjuk az ilyen semmilyen tartalommal nem bíró tegeket mondjuk 0-ra állítani kiolvasáskor? Viszont szükség lenne rájuk még ha üresek is, mert egy adatbázisba tölteném be.
Köszi a válaszokat!
- 1657 megtekintés
Hozzászólások
Kod, pelda, hanyas java... input, input, more input!
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Szia!
Ez lenne a kódom:
valami egy string xml.
< OBJEKTUM >
< FUNCTION >
< ID > 1 < /ID >
< NEV > VALAMI < /NEV >
< MODUL >< ID > 12 < /ID >< /MODUL >
< /FUNCTION >
< OBJEKTUM >
< FUNCTION >
< ID > 1 < /ID >
< NEV > VALAMI < /NEV >
< MODUL >< ID/ >< /MODUL > <- itt dobja el a kanalat
< /FUNCTION >
doc = b.parse(new InputSource(new StringReader(valami)));
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr = xpath.compile("/OBJEKTUM/FUNCTION/NEV");
XPathExpression id = xpath.compile("/OBJEKTUM/FUNCTION/MODUL/ID");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
Object result2 = id.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for(int a = 0; a < nodes.getLength();a++){
String node = (nodes.item(a).getTextContent() != "") ? ids.item(a).getTextContent() : "0";
System.out.print(a+"-"+node+"\n");
}
Ezzel azt szeretném, hogy ha talál olyan teget ami üres akkor legyen értéke 0 és így már talán nem dob hibát. A setNodeValue és a setTextContent nem működött. Hálás lennék valami ötletért. Köszönöm
és ez a hibaüzenet:
Exception in thread "main" java.lang.NullPointerException
at loader.Main.storedFunctions(Main.java:271)
at loader.Main.main(Main.java:32)
on all of them solvable
- A hozzászóláshoz be kell jelentkezni
Egy info kimaradt. Kitalalod, melyik?
Probaltad mar, hogy a tag nem igy ures, hanem <ID></ID>
--
()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Java verzió: 1.6.0_07
Az a baj, hogy így kapom az xml-t, bár lehet az lesz a megoldás, hogy végigjárom és minden teget lecserélek -re? Már nincs ötletem.
on all of them solvable
- A hozzászóláshoz be kell jelentkezni
Abban a 271-es sorban mi van egészen pontosan? Nem lenne egyszerűbb ott megfogni a null-t?
Esetleg az nem a Object result2 = id.evaluate(doc, XPathConstants.NODESET);
sor?
- A hozzászóláshoz be kell jelentkezni
Először azt hittem a JRE valamelyik könyvtárából jön a null pointer exception. De nem, hanem a te kódodból. Tehát az exception-t dobó sort kell csak megnézned, hogy mi lesz null és lekezelni azt az esetelt a programból.
- A hozzászóláshoz be kell jelentkezni
< MODUL >< ID/ >< /MODUL > <- itt dobja el a kanalat
Ebben a sorban az eredetiben is < ID/ > van mert ha igen akkor ez igy hibatlan
valamint ha csak masoltad az xml fajlbol a reszletet akkor az igy nem helyesen formalt
- A hozzászóláshoz be kell jelentkezni
Tényleg, bocs az objektum rossz helyen van lezárva.
Hogyan tudnám megfogni a null-t, feltételekre nem reagál...
Agy,hogy van ez a hiba 6000 sor helyett csak 5000-et kapok vissza mert 1000-nek nincs értéke. Már megpróbáltam mindent (szinte). Nincs valami javaslatotok?
Köszi!
on all of them solvable
- A hozzászóláshoz be kell jelentkezni
Sziasztok!
Megpróbálom összefoglalni a problémámat, lehet, hogy ezzel átfogóbb képet kaptok.
Tehát a feladat az lenne, hogy egy hatalmas xml álományból betöltsek adatokat adatbázisba.
(ezért is lenne szükségem az üres tegekre).
Jelenleg az xml egy string bufferben van, onnan olvasom ki.
doc = b.parse(new InputSource(new StringReader(xml)));
az xml struktúra szerintem ebben az esetben teljesen mindegy. Az a lényeg, hogy ha bejárom a fát akkor az üres tegekre is kapjak vissza legalább egy false értéket, innen már tudok neki értéket adni és szuper minden.
De nem történik meg a visszatérés, mert az xpath csak a textcontent-et olvassa ki, tehát ami üres azt nem is nézi meg. Olyan megoldást keresek amivel mident be tudok olvasni és mindenre tudok dobni egy outputot. Így próbáltam:
doc = b.parse(new InputSource(new StringReader(valami)));
NodeList id = new XPathHelper().processXPath("/OBJEKTUM/ALKALMAZAS/ID", doc.getDocumentElement());
NodeList mod_id = new XPathHelper().processXPath("/OBJEKTUM/ALKALMAZAS/MODUL/ID", doc.getDocumentElement());
Így tök jól ki tudom olvasni a tegek tartalmait:
for (int i = 0; i < id.getLength(); i++) {
String str = "INSERT INTO APPS VALUES ('"+id+"', '"+mod_id+"')";
func.execute(str);
}
tehát addig megyünk amennyi id van. Mert id mindenhol van. De mod_id nem, ahol nincs ott továbbmegy, majd ennyivel megrövidűl a futási ciklusainak a száma. Tehát ha van 4000 node-om, akkor elkez menni a ciklus, olvas olvas, majd hopp itt nincs mod_id akkor átlép. Ilyenkor a mod_id már csak 3999 és így tovább. Esetemben a végén 300al kevesebb jön ki. Sőtt ugye csak addig fut amig el nem éri a mod_id mennyiségét. Egyszóval szar. Klép null pointer hibával mert menne tovább, de nem tud, mert a mod_id-nek elérte az utolsó tagját míg id-ból még van bőven és ez így már necce az id-mod_id párok miatt is. MEg vagyok lőve. Lenne erre valami javaslat, vagy esetleg gyakorlati példa. Pár hete nyúzom a java-t és lehet csak nekem ilyen keszekusza ez a probléma vagy én nem tudom jól lemondani, de nem boldogulok vele. Sokat segítenétek ha sikerüle erre valami jó megoldást találni.
Előre is köszönök mindent!
Üdv,
Tibi
on all of them solvable
- A hozzászóláshoz be kell jelentkezni
Továbbra is áll a kérdésem: Miért nem a null pointer hiba okát vizsgálod?
Te magad írtad:
at loader.Main.storedFunctions(Main.java:271)
Nosza, nézd meg ott mi van.
- A hozzászóláshoz be kell jelentkezni
Abban a sorban csak ennyi van:
String str = "INSERT INTO FUNC VALUES ('"+ids.item(i).getTextContent()+"', '"+nev.item(i).getTextContent()+"', '"+ log_id.item(i).getTextContent() +"', '"+leiras.item(i).getTextContent()+"', '"+tipus.item(i).getTextContent()+"')";
és itt van az a probléma, hogy a log_id-k száma kevesebb mint az ids-é. Mert az üres elemeket valamiért nem olvassa ki.
on all of them solvable
- A hozzászóláshoz be kell jelentkezni
Nem vagyok nagy java guru de mi lenne ha null pointer hibat okozo sort egy try catch blokkba raknad es lekezelned a kivetelt. Tehat nem a for ciklust csak az insert utasitast.
- A hozzászóláshoz be kell jelentkezni
Kipróbáltam a megadott kódot és nálam korrektül lefutott. Egy-két módosítást bele kellett raknom, mert pl. az XML sem volt well-formed, valamint egy string összehasonlítás is rosszul volt megírva. String-et nem != -vel hasonlítunk, hanem az .equals-szal, vagy .lenght()-szel a hosszát nézzük.
Itt a kód:
String xml = "<?xml version=\"1.0\"?>" +
"< root > < OBJEKTUM >" +
" < FUNCTION >" +
" < ID > 1 < /ID >" +
" < NEV > VALAMI < /NEV >" +
" < MODUL >< ID > 12 < /ID >< /MODUL >" +
" < /FUNCTION >" +
" < /OBJEKTUM >" +
" < OBJEKTUM >" +
" < FUNCTION >" +
" < ID > 1 < /ID >" +
" < NEV > VALAMI < /NEV >" +
" < MODUL >< ID/ >< /MODUL >" +
" < /FUNCTION >" +
" < /OBJEKTUM >" +
" < OBJEKTUM >" +
" < FUNCTION >" +
" < ID > 1 < /ID >" +
" < NEV > VALAMI < /NEV >" +
" < MODUL >< ID > 12 < /ID >< /MODUL >" +
" < /FUNCTION >" +
" < /OBJEKTUM >" +
"< /root >";
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
try {
XPathExpression expr = xpath.compile("/root/OBJEKTUM/FUNCTION/NEV");
XPathExpression id = xpath.compile("/root/OBJEKTUM/FUNCTION/MODUL/ID");
InputSource src = new InputSource(new StringReader(xml));
Object result = expr.evaluate(src, XPathConstants.NODESET);
src = new InputSource(new StringReader(xml));
Object result2 = id.evaluate(src, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
NodeList ids = (NodeList) result2;
for(int a = 0; a < nodes.getLength();a++){
String node = (ids.item(a).getTextContent().length() > 0) ? ids.item(a).getTextContent() : "0";
System.out.print(nodes.item(a).getTextContent()+"-"+node+"\n");
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
Erre ez íródik ki:
VALAMI - 12
VALAMI -0
VALAMI - 12
- A hozzászóláshoz be kell jelentkezni
Köszönöm a kódot! Ez így tényleg működőképes. Viszont van egy olyan eset is amikor nem tud lefutni ez a kód sem. Mégpedig az, hogy amikor az üres id-k nem így szerepelnek, hogy:
...
< alkalmazas >
< modul >
< id />
< /modul >
< /alkalmazas >
...
hanem így:
...
< alkalmazas >
< modul />
< /alkalmazas >
...
így jelenik meg az xmlemben ha nincs modul id, tehát a id teget is kihagyja. Talán írnom kellene egy kivételkezelést nullpointerre?
Köszönöm!
T.
on all of them solvable
- A hozzászóláshoz be kell jelentkezni
> Talán írnom kellene egy kivételkezelést nullpointerre?
Ajvé. Hosszú lesz ez így...
- A hozzászóláshoz be kell jelentkezni
Attól van NullPointerExceptionod az első példában, hogy a getTextContent bal oldalán null áll. Ezt úgy idézed elő, hogy két nodelistet csinálsz, egyet a névnek egyet az id-nak, de ha hiányzik egy id node, akkor az egyik 5 hosszú a másik meg 4. Ezért amikor a ciklus elér az 5. iterációra, az ids.item(5) értéke null lesz.
A második példában attól van NullPE, hogy a getTextContent értéke null abban az esetben, ha az ID node text értéke üres (<id></id>), de ott is meg van hívva rajta a length függvény!
(A lényeg, hogy mindkét esetben a . operátor bal oldalán null áll)
Egyébként nem csak NullPE-d van, hanem ha mondjuk a második nodeból hiányzik az ID node, akkor elcsúszik egymáshoz képest a két lista. Ha ezt úgy oldod meg, hogy elkapod az exceptiont és ott nullát állítasz be, akkor az utolsó rekordhoz irsz hibásan nullát, holott a másodiknál hiányzott.
Szerintem így lehet a legelegánsabban megoldani (valszeg van benne gépelési hiba, mert nem próbáltam lefuttatni). A közös nodeot kérem le nodelistbe, és azon belül az név és az id két relatív xpath-os lekérés. Igy garantáltan egymáshoz tartozó adatokat tartalmaznak. A másik, hogy az XPathFactory-s vackolás helyett érdemes használni az XPathAPI függvényeit:
NodeList nl = XPathAPI.selectNodeList(doc, "/OBJEKTUM/FUNCTION");
for(int i=0; i < nl.getLength(); i++) {
Node r1 = XPathAPI.selectSingleNode(nl.item(i), "/NEV/text()");
Node r2 = XPathAPI.selectSingleNode(nl.item(i), "/MODUL/ID/text()");
String nev = null, id = null;
if(r1 != null)
nev = r1.getNodeValue();
else
throw new RuntimeException("hiba: nincs nev node");
if(r2 != null)
id = r2.getNodeValue();
// az id kétféleképpen is lehet null:
// 1, nincs id tagnode -> r2 = null
// 2, van id tagnode de üres <id></id> : ekkor a
// getNodeValue ad vissza nullt emlékeim szerint
if(id == null)
id= "0";
}
- A hozzászóláshoz be kell jelentkezni
Köszönöm, hogy megfogalmaztad helyettem a problémámat :). Pont erre gondoltam. A megoldásod teljesen jól működik, nagyon köszönöm a segítségedet!
Csak annyit a kódhoz, hogy csak annyi a hiba benne, hogy a simpleNode függvénynek a node elérést úgy kell megadni, hogy nem kezdődhet / jellel. De ezt írtad is, hogy lehet gépelési hiba. Csak ennyi volt benne.
Köszönöm mindenkienk a segítséget!
Üdvözlettel,
Tibi
on all of them solvable
- A hozzászóláshoz be kell jelentkezni
Nincs mit! Tényleg lemaradt a "."-t az elejéről ("./"-t akartam), de az is jó, ha leveszed a "/"-t, sőt még talán szebb is, bár én már megszoktam az elsőt. :-)
- A hozzászóláshoz be kell jelentkezni