Как читать XML с помощью XPath в Java

Я хочу читать XML-данные с помощью XPath в Java, поэтому для информации, которую я собрал, я не могу анализировать XML в соответствии с моим требованием.

вот что я хочу сделать:

Получите XML-файл из Интернета через его URL-адрес, затем используйте XPath для его анализа, я хочу создать в нем два метода. Один из них заключается в том, что я вводим идентификатор атрибута определенного узла, и я получаю все дочерние узлы в качестве результата, а во-вторых, я просто хочу получить только определенное значение дочернего узла

   http://www.rgagnonjavahowto.htm taxi   http://www.rgagnon/pbhowto.htm http://www.rgagnon/pbhowtonew.htm   http://www.rgagnon/jshowto.htm   http://www.rgagnon/vbshowto.htm   

В приведенном выше примере я хочу прочитать все элементы, если я ищу через @name, а также одну функцию, в которой я просто хочу, чтобы URL-адрес из @name ‘Javascript’ возвращал только один элемент узла.

Надеюсь, я очистил свой вопрос 🙂

Благодарю.

Кай

6 Solutions collect form web for “Как читать XML с помощью XPath в Java”

Вам нужно что-то вроде этого:

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(); XPathFactory xPathfactory = XPathFactory.newInstance(); XPath xpath = xPathfactory.newXPath(); XPathExpression expr = xpath.compile(); 

Затем вы вызываете expr.evaluate() проходящую в документе, определенном в этом коде, и возвращаемом типе, который вы ожидаете, и приводите результат к типу объекта результата.

Если вам нужна помощь с конкретными выражениями XPath, вы, вероятно, должны задавать ее как отдельные вопросы (если это не был ваш вопрос в первую очередь здесь, я понял, что ваш вопрос заключается в том, как использовать API в Java).

Изменить: (Ответ на комментарий): Это выражение XPath предоставит вам текст первого элемента URL в PowerBuilder:

 /howto/topic[@name='PowerBuilder']/url/text() 

Это даст вам второе:

 /howto/topic[@name='PowerBuilder']/url[2]/text() 

Вы получите это с помощью этого кода:

 expr.evaluate(doc, XPathConstants.STRING); 

Если вы не знаете, сколько URL-адресов находится в данном узле, вы должны сделать что-то вроде этого:

 XPathExpression expr = xpath.compile("/howto/topic[@name='PowerBuilder']/url"); NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 

А затем перейдем к NodeList.

Вы можете попробовать это.

Документ XML

Сохранить как employees.xml .

 < ?xml version="1.0" encoding="UTF-8"?>   29 Pankaj Male Java Developer   35 Lisa Female CEO   40 Tom Male Manager   25 Meghan Female Manager   

Класс Parser

Класс имеет следующие методы

  • Элемент списка
  • Метод, который вернет имя сотрудника для идентификатора ввода.
  • Метод, который будет возвращать список имени сотрудников с возрастом, превышающим возраст вступления.
  • Метод, который будет возвращать список имени работающих женщин.

Исходный код

 import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class Parser { public static void main(String[] args) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder; Document doc = null; try { builder = factory.newDocumentBuilder(); doc = builder.parse("employees.xml"); // Create XPathFactory object XPathFactory xpathFactory = XPathFactory.newInstance(); // Create XPath object XPath xpath = xpathFactory.newXPath(); String name = getEmployeeNameById(doc, xpath, 4); System.out.println("Employee Name with ID 4: " + name); List names = getEmployeeNameWithAge(doc, xpath, 30); System.out.println("Employees with 'age>30' are:" + Arrays.toString(names.toArray())); List femaleEmps = getFemaleEmployeesName(doc, xpath); System.out.println("Female Employees names are:" + Arrays.toString(femaleEmps.toArray())); } catch (ParserConfigurationException | SAXException | IOException e) { e.printStackTrace(); } } private static List getFemaleEmployeesName(Document doc, XPath xpath) { List list = new ArrayList<>(); try { //create XPathExpression object XPathExpression expr = xpath.compile("/Employees/Employee[gender='Female']/name/text()"); //evaluate expression result on XML document NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); for (int i = 0; i < nodes.getLength(); i++) list.add(nodes.item(i).getNodeValue()); } catch (XPathExpressionException e) { e.printStackTrace(); } return list; } private static List getEmployeeNameWithAge(Document doc, XPath xpath, int age) { List list = new ArrayList<>(); try { XPathExpression expr = xpath.compile("/Employees/Employee[age>" + age + "]/name/text()"); NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); for (int i = 0; i < nodes.getLength(); i++) list.add(nodes.item(i).getNodeValue()); } catch (XPathExpressionException e) { e.printStackTrace(); } return list; } private static String getEmployeeNameById(Document doc, XPath xpath, int id) { String name = null; try { XPathExpression expr = xpath.compile("/Employees/Employee[@id='" + id + "']/name/text()"); name = (String) expr.evaluate(doc, XPathConstants.STRING); } catch (XPathExpressionException e) { e.printStackTrace(); } return name; } } 

Пример запуска:

Файл xml:

   Snow Crash Neal Stephenson Spectra 0553380958 14.95   Burning Tower Larry Niven Jerry Pournelle Pocket 0743416910 5.99   Zodiac Neal Stephenson Spectra 0553573862 7.50    

Код Java:

 import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; try { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); Document doc = docBuilder.parse (new File("c:\\tmp\\my.xml")); // normalize text representation doc.getDocumentElement().normalize(); System.out.println ("Root element of the doc is " + doc.getDocumentElement().getNodeName()); NodeList listOfBooks = doc.getElementsByTagName("book"); int totalBooks = listOfBooks.getLength(); System.out.println("Total no of books : " + totalBooks); for(int i=0; i 

Вот пример обработки xpath с помощью vtd-xml … для обработки данных с большой нагрузкой он не имеет себе равных. вот недавняя статья по этому вопросу. Обработка XML с помощью Java – Performance Benchmark

 import com.ximpleware.*; public class changeAttrVal { public static void main(String s[]) throws VTDException,java.io.UnsupportedEncodingException,java.io.IOException{ VTDGen vg = new VTDGen(); if (!vg.parseFile("input.xml", false)) return; VTDNav vn = vg.getNav(); AutoPilot ap = new AutoPilot(vn); XMLModifier xm = new XMLModifier(vn); ap.selectXPath("/*/place[@id=\"p14\" and @initialMarking=\"2\"]/@initialMarking"); int i=0; while((i=ap.evalXPath())!=-1){ xm.updateToken(i+1, "499");// change initial marking from 2 to 499 } xm.output("new.xml"); } } в import com.ximpleware.*; public class changeAttrVal { public static void main(String s[]) throws VTDException,java.io.UnsupportedEncodingException,java.io.IOException{ VTDGen vg = new VTDGen(); if (!vg.parseFile("input.xml", false)) return; VTDNav vn = vg.getNav(); AutoPilot ap = new AutoPilot(vn); XMLModifier xm = new XMLModifier(vn); ap.selectXPath("/*/place[@id=\"p14\" and @initialMarking=\"2\"]/@initialMarking"); int i=0; while((i=ap.evalXPath())!=-1){ xm.updateToken(i+1, "499");// change initial marking from 2 to 499 } xm.output("new.xml"); } } 

Развернувшись на отличный ответ от @bluish и @Yishai, вот как вы создаете атрибуты NodeLists и node, поддерживающие iteratorы, то есть интерфейс for(Node n: nodelist) .

Используйте его так:

 NodeList nl = ... for(Node n : XmlUtil.asList(nl)) {...} 

а также

 Node n = ... for(Node attr : XmlUtil.asList(n.getAttributes()) {...} 

Код:

 /** * Converts NodeList to an iterable construct. * From: https://stackoverflow.com/a/19591302/779521 */ public final class XmlUtil { private XmlUtil() {} public static List asList(NodeList n) { return n.getLength() == 0 ? Collections.emptyList() : new NodeListWrapper(n); } static final class NodeListWrapper extends AbstractList implements RandomAccess { private final NodeList list; NodeListWrapper(NodeList l) { this.list = l; } public Node get(int index) { return this.list.item(index); } public int size() { return this.list.getLength(); } } public static List asList(NamedNodeMap n) { return n.getLength() == 0 ? Collections.emptyList() : new NodeMapWrapper(n); } static final class NodeMapWrapper extends AbstractList implements RandomAccess { private final NamedNodeMap list; NodeMapWrapper(NamedNodeMap l) { this.list = l; } public Node get(int index) { return this.list.item(index); } public int size() { return this.list.getLength(); } } } 

Прочитайте XML-файл с помощью XPathFactory, SAXParserFactory и StAX (JSR-173) .

Использование XPath получает узел и его дочерние данные.

 public static void main(String[] args) { String xml = "" + "" + "JavaJavascriptSelenium" + "javascriptYash-777" + ""; String jsonNameSpaces = "{'soapenv':'http://schemas.xmlsoap.org/soap/envelope/'," + "'Yash':'http://Yash.stackoverflow.com/Services/Yash'}"; String xpathExpression = "//Yash:Data"; Document doc1 = getDocument(false, "fileName", xml); getNodesFromXpath(doc1, xpathExpression, jsonNameSpaces); System.out.println("\n===== ***** ====="); Document doc2 = getDocument(true, "./books.xml", xml); getNodesFromXpath(doc2, "//person", "{}"); } static Document getDocument( boolean isFileName, String fileName, String xml ) { Document doc = null; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); factory.setNamespaceAware(true); factory.setIgnoringComments(true); factory.setIgnoringElementContentWhitespace(true); DocumentBuilder builder = factory.newDocumentBuilder(); if( isFileName ) { File file = new File( fileName ); FileInputStream stream = new FileInputStream( file ); doc = builder.parse( stream ); } else { doc = builder.parse( string2Source( xml ) ); } } catch (SAXException | IOException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } return doc; } /** * ELEMENT_NODE[1],ATTRIBUTE_NODE[2],TEXT_NODE[3],CDATA_SECTION_NODE[4], * ENTITY_REFERENCE_NODE[5],ENTITY_NODE[6],PROCESSING_INSTRUCTION_NODE[7], * COMMENT_NODE[8],DOCUMENT_NODE[9],DOCUMENT_TYPE_NODE[10],DOCUMENT_FRAGMENT_NODE[11],NOTATION_NODE[12] */ public static void getNodesFromXpath( Document doc, String xpathExpression, String jsonNameSpaces ) { try { XPathFactory xpf = XPathFactory.newInstance(); XPath xpath = xpf.newXPath(); JSONObject namespaces = getJSONObjectNameSpaces(jsonNameSpaces); if ( namespaces.size() > 0 ) { NamespaceContextImpl nsContext = new NamespaceContextImpl(); Iterator< ?> key = namespaces.keySet().iterator(); while (key.hasNext()) { // Apache WebServices Common Utilities String pPrefix = key.next().toString(); String pURI = namespaces.get(pPrefix).toString(); nsContext.startPrefixMapping(pPrefix, pURI); } xpath.setNamespaceContext(nsContext ); } XPathExpression compile = xpath.compile(xpathExpression); NodeList nodeList = (NodeList) compile.evaluate(doc, XPathConstants.NODESET); displayNodeList(nodeList); } catch (XPathExpressionException e) { e.printStackTrace(); } } static void displayNodeList( NodeList nodeList ) { for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); String NodeName = node.getNodeName(); NodeList childNodes = node.getChildNodes(); if ( childNodes.getLength() > 1 ) { for (int j = 0; j < childNodes.getLength(); j++) { Node child = childNodes.item(j); short nodeType = child.getNodeType(); if ( nodeType == 1 ) { System.out.format( "\n\t Node Name:[%s], Text[%s] ", child.getNodeName(), child.getTextContent() ); } } } else { System.out.format( "\n Node Name:[%s], Text[%s] ", NodeName, node.getTextContent() ); } } } static InputSource string2Source( String str ) { InputSource inputSource = new InputSource( new StringReader( str ) ); return inputSource; } static JSONObject getJSONObjectNameSpaces( String jsonNameSpaces ) { if(jsonNameSpaces.indexOf("'") > -1) jsonNameSpaces = jsonNameSpaces.replace("'", "\""); JSONParser parser = new JSONParser(); JSONObject namespaces = null; try { namespaces = (JSONObject) parser.parse(jsonNameSpaces); } catch (ParseException e) { e.printStackTrace(); } return namespaces; } 

Документ XML

 < ?xml version="1.0" encoding="UTF-8"?>   Yash M 22   Bill Gates 46   Steve Jobs 40   

Out put для данного XPathExpression:

 String xpathExpression = "//person/first"; /*OutPut: Node Name:[first], Text[Yash] Node Name:[first], Text[Bill] Node Name:[first], Text[Steve] */ String xpathExpression = "//person"; /*OutPut: Node Name:[first], Text[Yash] Node Name:[last], Text[M] Node Name:[age], Text[22] Node Name:[first], Text[Bill] Node Name:[last], Text[Gates] Node Name:[age], Text[46] Node Name:[first], Text[Steve] Node Name:[last], Text[Jobs] Node Name:[age], Text[40] */ String xpathExpression = "//Yash:Data"; /*OutPut: Node Name:[Yash:Tags], Text[Java] Node Name:[Yash:Tags], Text[Javascript] Node Name:[Yash:Tags], Text[Selenium] Node Name:[Yash:Top], Text[javascript] Node Name:[Yash:User], Text[Yash-777] */ 

См. Эту ссылку для нашей собственной реализации NamespaceContext

Давайте будем гением компьютера.