Почему не работает поиск по значению атрибута XPATH?

190
24 июня 2019, 04:50
public class Main {
public static void main(String[] args) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException {
    Scanner scn=new Scanner(System.in);
    DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
    DocumentBuilder db=dbf.newDocumentBuilder();
    Document d=db.parse("products.xml");
    Element element=d.getDocumentElement();
    String h=scn.nextLine();
    XPath xp=XPathFactory.newInstance().newXPath();
    XPathExpression expr2 = xp.compile(h);
    NodeList nl2=(NodeList)xp.compile("//products/child::*").evaluate(d, XPathConstants.NODESET);
    for(int i=0; i<nl2.getLength(); i++){
    System.out.println(nl2.item(i).getLocalName());
    System.out.println(nl2.item(i).getAttributes().item(i).getNodeValue());
    if(h.equals(nl2.item(i).getAttributes().item(i).getNodeValue())){
        Element element3 = (Element) xp.evaluate(String.format("//*[@%s='%s']", nl2.item(i).getAttributes(), nl2.item(i).getAttributes().item(i).getNodeValue() ), d, XPathConstants.NODE);
        System.out.println(element3.getNodeName());
        System.out.println(element3.getTextContent());
    }}
}

}

данные:

 <?xml version="1.0" encoding="UTF-8"?>
<products>
    <product name="eee">
        <id>p01</id>
        <name>Product1</name>
        <price>100</price>
    </product>
    <product name="pp">
        <id>p02</id>
        <name>Product2</name>
        <price>200</price>
    </product>
    <product name="rr">
        <id>p03</id>
        <name>Product3</name>
        <price>300</price>
    </product>
</products>
Answer 1

Одна из ошибок в том что для атрибута не нужно брать item по i, всегда будет 0.

nl2.item(i).getAttributes().item(0).getNodeValue();

Второе вы не правильно формируете expression, для нахождения имени нужно использовать не nl2.item(i).getAttributes(), а nl2.item(i).getAttributes().item(0).getNodeName()

Если я правильно понял, вам нужно найти продукт с определенным именем, ниже код как я это вижу

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.StringReader;
import java.util.Objects;
import java.util.Scanner;
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;
public class Main {
    private static final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                                      "<products>\n" +
                                      "    <product name=\"eee\">\n" +
                                      "        <id>p01</id>\n" +
                                      "        <name>Product1</name>\n" +
                                      "        <price>100</price>\n" +
                                      "    </product>\n" +
                                      "    <product name=\"pp\">\n" +
                                      "        <id>p02</id>\n" +
                                      "        <name>Product2</name>\n" +
                                      "        <price>200</price>\n" +
                                      "    </product>\n" +
                                      "    <product name=\"rr\">\n" +
                                      "        <id>p03</id>\n" +
                                      "        <name>Product3</name>\n" +
                                      "        <price>300</price>\n" +
                                      "    </product>\n" +
                                      "</products>";

    public static void main(String args[]) throws Exception {
        System.out.print("Введите имя продукта:");
        String productName = new Scanner(System.in).nextLine();
        ProductXmlSearcher searcher = new ProductXmlSearcher(getDocument());
        Element product = searcher.getProductByName(productName);
        if (Objects.nonNull(product)) {
            System.out.println(product.getNodeName());
            System.out.println(product.getTextContent());
        } else {
            System.out.println("Продукт не найден для:" + productName);
        }

    }
    private static Document getDocument() throws ParserConfigurationException, SAXException, IOException {
        DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        InputSource is = new InputSource(new StringReader(xml));
        return db.parse(is);
    }
    static class ProductXmlSearcher {
        private final Document document;
        private final XPath xPath;
        ProductXmlSearcher(Document document) {
            this.document = document;
            this.xPath = XPathFactory.newInstance().newXPath();
        }
        public Element getProductByName(String productName) {
            String expression = "//products/*[@name='" + productName + "']";
            try {
                XPathExpression compiledXPath = xPath.compile(expression);
                return (Element) compiledXPath.evaluate(document, XPathConstants.NODE);
            } catch (XPathExpressionException e) {
                throw new RuntimeException("Element not found for expression: " + expression, e);
            }
        }
    }
}
READ ALSO
как в java проверить вводные данные на тип

как в java проверить вводные данные на тип

Подскажите новичку, как в java проверить вводные данные на тип? нужно получить вводные данные типа int, а не какие другиеСпасибо, заранее) P

190
Как получить разные части из одного String?

Как получить разные части из одного String?

Есть текстовый файл со следующим текстом

182
Подскажите библиотеки для рисования (android) [закрыт]

Подскажите библиотеки для рисования (android) [закрыт]

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

170
Странное выполнение блока finally

Странное выполнение блока finally

Всем приветПри регистрации пользователя ему отправляется email с подтверждением через метод sendActiovationEmail

251