21. august 2008 - 16:29
Der er
15 kommentarer og 1 løsning
XPath forespørgsel med 2 attributter
Jeg har følgende xml, hvor jeg gerne vil kunne finde f.eks. teksten "Annuller" ved et enkelt XPath opslag. Jeg tænkte, at jeg kunne bruge følgende udtryk, og trække TextContent ud fra noden, men jeg finder ingen node... "//Language/Group[@name='General']/String[@name='Cancel']" Hvordan gør jeg det så?? <Language> <Group name="General"> <String name="Ok">Ok</String> <String name="Cancel">Annuller</String> </Group> <Group name="Login"> <String name="Username">Brugernavn</String> <String name="Password">Adgangskode</String> </Group> </Language>
Annonceindlæg fra Infor
21. august 2008 - 16:46
#1
Det ser da umiddelbart korrekt ud... der må være nogle andre omstændigheder som gør at du ikke får fat i en node. Kan du vise hvordan du forsøger at udføre denne XPath?
28. august 2008 - 12:29
#2
Jeg har en metode, som ser således ud, hvor "root" er rod Element i dokumentet (og instansvariabel), som er indlæst: public String getString(String group, String key){ String xpathSelector = "//Language/Group[@name='" + group + "']/String[@name='" + key + "']"; XPath xpath = XPathFactory.newInstance().newXPath(); NodeList nodeList; try { nodeList = (NodeList)xpath.evaluate(xpathSelector, root, XPathConstants.NODESET); if(nodeList != null) { Element element = (Element)nodeList.item(0); Node n = element; return n.getTextContent(); } } catch(XPathExpressionException e) { e.printStackTrace(); } return key; } Der bliver smidt en NullPointerException, idet 'n' er null, altså i linjen "return n.getTextContent();"
28. august 2008 - 12:32
#3
Gør jeg det uden XPath fungerer det: public String getString(String group, String key){ NodeList elements = root.getElementsByTagName("Group"); for(int i=0; i < elements.getLength(); i++){ String groupCandidate = elements.item(i).getAttributes().item(0).getTextContent(); if(stringGroupCandidate.equals(group)){ NodeList children = ((Element)elements.item(i)).getElementsByTagName("String"); for(int c=0; c < children.getLength(); c++){ String stringCandidate = children.item(c).getAttributes().item(0).getTextContent(); if(stringCandidate.equals(key)){ return children.item(c).getTextContent(); } } } } return key; }
28. august 2008 - 12:32
#4
Spørgsmålet er så, hvordan jeg får XPath metoden til at virke...
28. august 2008 - 12:47
#5
Hmm... umiddelbart noget i stil med dette (jeg er dog ikke helt sikker på om dette er den præcise syntaks): public String getString(String group, String key){ try { XmlNode xNod = root.DocumentElement.SelectSingleNode("//Language/Group[@name='" + group + "']/String[@name='" + key + "']"); if(xNod != null) return xNod.getTextContent(); } catch(Exception e) { // whatever... } return key; }
28. august 2008 - 13:31
#6
Hmm... jeg kan slet ikke få det til at compile. Hvilken parser er det, at du anvender?? Jeg forsøger at bruge DOM (tror jeg nok, at den hedder). Jeg importerer i hvert fald javax.xml.parsers, javax.xml.transform og javax.xml.xpath
28. august 2008 - 13:40
#7
Ach sooo... Jeg sidder og koder i C#... :-) Jeg kan desværre ikke hjælpe dig med Java - sorry.
28. august 2008 - 13:45
#8
Ah, ja det er bedst, hvis vi snakker samme sprog ;) Men tak for forsøget... andre bud er meget velkomne!
28. august 2008 - 15:31
#9
Der er et eller andet mystisk her. Jeg proevede med din XML fil og foelgende kode: import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class XPathFun { public static void main(String[] args) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse("C:\\xpathfun.xml"); XPath xpath = XPathFactory.newInstance().newXPath(); NodeList list = (NodeList)xpath.evaluate("//Language/Group[@name='General']/String[@name='Cancel']", doc.getDocumentElement(), XPathConstants.NODESET); Element elm = (Element)list.item(0); System.out.println(elm.getTextContent()); } } Den virker !! Check indholdet af: - xpathSelector - root
28. august 2008 - 15:32
#10
Og saa ville jeg aldrig bruge .getTextContext() !
16. september 2008 - 11:36
#11
Først og fremmest vil jeg beklage den lange responstid... Og dernæst, så har du fuldstændig ret i, Arne V, at der er noget mystisk. Og det mystiske viste sig at være en fejl i xml'en, mens koden hele tiden har fungeret, som den burde! :S Men smid et svar, så jeg kan belønne dig for at guide mig ind på sporet! Og hvorfor ville du aldrig bruge .getTextContext()? Hvad ville du bruge i stedet for?
16. september 2008 - 12:08
#12
svar
16. september 2008 - 12:09
#13
getTextContent() returnerer al text ogsaa fra undernoder, saa det taber strukturen. Jeg ville lade XPath'en vaelge den text jeh skulle bruge.
16. september 2008 - 12:13
#14
Oh, du kan vel ikke lige demonstrere, hvordan jeg gør det, når det altid blot er elementets tekst, at jeg skal have fat i? Se evt. eksemplet ovenfor...
16. september 2008 - 12:36
#15
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; public class XPathFun { public static void main(String[] args) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse("C:\\xpathfun.xml"); XPath xpath = XPathFactory.newInstance().newXPath(); Node cantxt = (Node)xpath.evaluate("//Language/Group[@name='General']/String[@name='Cancel']/text()", doc.getDocumentElement(), XPathConstants.NODE); System.out.println(cantxt.getNodeValue()); } }
16. september 2008 - 13:12
#16
Jeg takker og bukker :)
Kurser inden for grundlæggende programmering