Что я делаю не так с XPath? - PullRequest
       0

Что я делаю не так с XPath?

1 голос
/ 25 августа 2010

Я пытаюсь манипулировать схемой xsd как документом xml, что, по моему мнению, не должно быть проблемой.Но столкнулся с проблемами с XPath.Какой бы XPath я ни пробовал, он ничего не возвращает.Пробовал с или без пространств имен, но безуспешно.Пожалуйста, помогите мне понять, что я делаю неправильно?

Мой xml:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mydomain.com" xmlns="http://www.mydomain.com" elementFormDefault="qualified">

  <xs:complexType name="Label">
    <xs:choice maxOccurs="unbounded" minOccurs="0">
      <xs:element name="Listener"/>
    </xs:choice>
  </xs:complexType>

</xs:schema>

и код приложения:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setValidating(false);
domFactory.setNamespaceAware(true);
domFactory.setIgnoringComments(true);
domFactory.setIgnoringElementContentWhitespace(true);

try {
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document dDoc = builder.parse("C:/Temp/test.xsd");

    // This part works
    Node rootNode = dDoc.getElementsByTagName("xs:schema").item(0);
    System.out.println(rootNode.getNodeName());

    // This part doesn't work
    XPath xPath1 = XPathFactory.newInstance().newXPath();
    NodeList nList1 = (NodeList) xPath1.evaluate("//xs:schema", dDoc, XPathConstants.NODESET);  
    System.out.println(nList1.item(0).getNodeName());

    // This part doesn't work
    XPath xPath2 = XPathFactory.newInstance().newXPath();
    NodeList nList2 = (NodeList) xPath2.evaluate("//xs:element", rootNode, XPathConstants.NODESET); 
    System.out.println(nList2.item(0).getNodeName());

}catch (Exception e){
    e.printStackTrace();
}

Ответы [ 3 ]

4 голосов
/ 25 августа 2010

Установить контекст пространства имен, используя XPath.setNamespaceContext (). Это связывает префикс xs с пространством имен http://www.w3.org/2001/XMLSchema.

3 голосов
/ 25 августа 2010

Внесены изменения в ваш код.Работает:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.xml.namespace.NamespaceContext;
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;
import org.w3c.dom.NodeList;

public class XPathtest {
    public static void main(String[] args) {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory
                .newInstance();
        domFactory.setValidating(false);
        domFactory.setNamespaceAware(true);
        domFactory.setIgnoringComments(true);
        domFactory.setIgnoringElementContentWhitespace(true);

        try {
            DocumentBuilder builder = domFactory.newDocumentBuilder();
            Document dDoc = builder.parse("C:/Temp/test.xsd");

            // This part works
            Node rootNode = dDoc.getElementsByTagName("xs:schema").item(0);
            System.out.println(rootNode.getNodeName());

            // This part doesn't work
            XPath xPath1 = XPathFactory.newInstance().newXPath();

            NamespaceContext nsContext = new NamespaceContext() {

                @Override
                public String getNamespaceURI(String prefix) {
                    return "http://www.w3.org/2001/XMLSchema";
                }

                @Override
                public String getPrefix(String namespaceURI) {
                    return "xs";
                }

                @Override
                public Iterator getPrefixes(String namespaceURI) {
                    Set s = new HashSet();
                    s.add("xs");
                    return s.iterator();
                }

            };

            xPath1.setNamespaceContext((NamespaceContext) nsContext);

            NodeList nList1 = (NodeList) xPath1.evaluate("//xs:schema", dDoc,
                    XPathConstants.NODESET);
            System.out.println(nList1.item(0).getNodeName());

            // This part doesn't work
            // XPath xPath2 = XPathFactory.newInstance().newXPath();
            NodeList nList2 = (NodeList) xPath1.evaluate("//xs:element",
                    rootNode, XPathConstants.NODESET);
            System.out.println(nList2.item(0).getNodeName());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
2 голосов
/ 25 августа 2010

Причина в том, что вы не указали, что означает xs. Анализатор xml должен знать URL-адрес пространства имен, xs - это просто идентификатор.

Вы можете продемонстрировать это самостоятельно, используя следующий код:

XPath xPath = XPathFactory.newInstance().newXPath();

SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
nsContext.addNamespace("t", "http://www.w3.org/2001/XMLSchema");
xPath.setNamespaceContext(nsContext);

xPath.evaluate("//t:schema", dDoc, XPathConstants.NODESET);

Вы видите, что теперь я использую идентификатор t вместо xs, но это не имеет значения, если вы используете тот же URL-адрес пространства имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...