कि प्रपत्र '// elementName' वापसी अशक्त जब स्रोत एक्सएमएल एक namespace उपसर्ग में हैं किसी भी XPath नीचे दिए गए उदाहरण कोड में है (में testWithNS()
देखना नीचे कोड)।क्यों केवल कुछ xPath अभिव्यक्ति नोड्स मिल रहा है जब एक्सएमएल एक नामस्थान उपसर्ग
जब स्रोत xml में नामस्थान उपसर्ग नहीं है तो सभी सूचीबद्ध XPath अभिव्यक्तियां नोड लौटाती हैं (testNoNS()
देखें)।
मुझे पता है कि मैं नेमस्पेस कॉन्टेक्स्ट (testWithNSContext()
में) स्थापित करके, एक्सएमएल को नेमस्पेस जागरूक दस्तावेज़ के रूप में पार्स करना और XPaths में नेमस्पेस उपसर्ग का उपयोग करके इसे हल कर सकता हूं। हालांकि मैं ऐसा नहीं करना चाहता क्योंकि मेरे वास्तविक कोड को नामस्थान उपसर्गों के साथ और बिना दोनों एक्सएमएल को संसाधित करने की आवश्यकता है।
मेरा प्रश्न क्यों यह केवल है:
- // परीक्षण
- // child1
- // grandchild1
- // child2
कि अशक्त लौटने के लिए, अभी तक testWithNS()
में अन्य सभी उदाहरण नोड लौटाते हैं?
आउटपुट
testNoNS()
test = found
/test = found
//test = found
//test/* = found
//test/child1 = found
//test/child1/grandchild1 = found
//test/child2 = found
//child1 = found
//grandchild1 = found
//child1/grandchild1 = found
//child2 = found
testWithNS()
test = found
/test = found
//test = *** NOT FOUND ***
//test/* = found
//test/child1 = found
//test/child1/grandchild1 = found
//test/child2 = found
//child1 = *** NOT FOUND ***
//grandchild1 = *** NOT FOUND ***
//child1/grandchild1 = found
//child2 = *** NOT FOUND ***
testWithNSContext()
ns1:test = found
/ns1:test = found
//ns1:test = found
//ns1:test/* = found
//ns1:test/ns1:child1 = found
//ns1:test/ns1:child1/ns1:grandchild1 = found
//ns1:test/ns1:child2 = found
//ns1:child1 = found
//ns1:grandchild1 = found
//ns1:child1/ns1:grandchild1 = found
//ns1:child2 = found
कोड
import java.io.StringReader;
import java.util.Iterator;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.junit.Test;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
public class XPathBugTest {
private String xmlDec = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
private String xml = xmlDec +
"<test>" +
" <child1>" +
" <grandchild1/>" +
" </child1>" +
" <child2/>" +
"</test>";
private String xmlNs = xmlDec +
"<ns1:test xmlns:ns1=\"http://www.wfmc.org/2002/XPDL1.0\">" +
" <ns1:child1>" +
" <ns1:grandchild1/>" +
" </ns1:child1>" +
" <ns1:child2/>" +
"</ns1:test>";
final XPathFactory xpathFactory = XPathFactory.newInstance();
final XPath xpath = xpathFactory.newXPath();
@Test
public void testNoNS() throws Exception {
System.out.println("\ntestNoNS()");
final Document doc = getDocument(xml);
isFound("test", xpath.evaluate("test", doc, XPathConstants.NODE));
isFound("/test", xpath.evaluate("/test", doc, XPathConstants.NODE));
isFound("//test", xpath.evaluate("//test", doc, XPathConstants.NODE));
isFound("//test/*", xpath.evaluate("//test/*", doc, XPathConstants.NODE));
isFound("//test/child1", xpath.evaluate("//test/child1", doc, XPathConstants.NODE));
isFound("//test/child1/grandchild1", xpath.evaluate("//test/child1/grandchild1", doc, XPathConstants.NODE));
isFound("//test/child2", xpath.evaluate("//test/child2", doc, XPathConstants.NODE));
isFound("//child1", xpath.evaluate("//child1", doc, XPathConstants.NODE));
isFound("//grandchild1", xpath.evaluate("//grandchild1", doc, XPathConstants.NODE));
isFound("//child1/grandchild1", xpath.evaluate("//child1/grandchild1", doc, XPathConstants.NODE));
isFound("//child2", xpath.evaluate("//child2", doc, XPathConstants.NODE));
}
@Test
public void testWithNS() throws Exception {
System.out.println("\ntestWithNS()");
final Document doc = getDocument(xmlNs);
isFound("test", xpath.evaluate("test", doc, XPathConstants.NODE));
isFound("/test", xpath.evaluate("/test", doc, XPathConstants.NODE));
isFound("//test", xpath.evaluate("//test", doc, XPathConstants.NODE));
isFound("//test/*", xpath.evaluate("//test/*", doc, XPathConstants.NODE));
isFound("//test/child1", xpath.evaluate("//test/child1", doc, XPathConstants.NODE));
isFound("//test/child1/grandchild1", xpath.evaluate("//test/child1/grandchild1", doc, XPathConstants.NODE));
isFound("//test/child2", xpath.evaluate("//test/child2", doc, XPathConstants.NODE));
isFound("//child1", xpath.evaluate("//child1", doc, XPathConstants.NODE));
isFound("//grandchild1", xpath.evaluate("//grandchild1", doc, XPathConstants.NODE));
isFound("//child1/grandchild1", xpath.evaluate("//child1/grandchild1", doc, XPathConstants.NODE));
isFound("//child2", xpath.evaluate("//child2", doc, XPathConstants.NODE));
}
@Test
public void testWithNSContext() throws Exception {
System.out.println("\ntestWithNSContext()");
final Document doc = getDocumentNS(xmlNs);
xpath.setNamespaceContext(new MyNamespaceContext());
isFound("ns1:test", xpath.evaluate("ns1:test", doc, XPathConstants.NODE));
isFound("/ns1:test", xpath.evaluate("/ns1:test", doc, XPathConstants.NODE));
isFound("//ns1:test", xpath.evaluate("//ns1:test", doc, XPathConstants.NODE));
isFound("//ns1:test/*", xpath.evaluate("//ns1:test/*", doc, XPathConstants.NODE));
isFound("//ns1:test/ns1:child1", xpath.evaluate("//ns1:test/ns1:child1", doc, XPathConstants.NODE));
isFound("//ns1:test/ns1:child1/ns1:grandchild1", xpath.evaluate("//ns1:test/ns1:child1/ns1:grandchild1", doc, XPathConstants.NODE));
isFound("//ns1:test/ns1:child2", xpath.evaluate("//ns1:test/ns1:child2", doc, XPathConstants.NODE));
isFound("//ns1:child1", xpath.evaluate("//ns1:child1", doc, XPathConstants.NODE));
isFound("//ns1:grandchild1", xpath.evaluate("//ns1:grandchild1", doc, XPathConstants.NODE));
isFound("//ns1:child1/ns1:grandchild1", xpath.evaluate("//ns1:child1/ns1:grandchild1", doc, XPathConstants.NODE));
isFound("//ns1:child2", xpath.evaluate("//ns1:child2", doc, XPathConstants.NODE));
}
private void isFound(String xpath, Object object) {
System.out.println(xpath + " = " + (object == null ? "*** NOT FOUND ***" : "found"));
}
private Document getDocument(final String xml) throws Exception {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
}
private Document getDocumentNS(final String xml) throws Exception {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
}
public class MyNamespaceContext implements NamespaceContext {
@Override
public String getNamespaceURI(String prefix) {
if ("ns1".equals(prefix)) {
return "http://www.wfmc.org/2002/XPDL1.0";
}
return XMLConstants.NULL_NS_URI;
}
@Override
public String getPrefix(String uri) {
throw new UnsupportedOperationException();
}
@Override
public Iterator getPrefixes(String uri) {
throw new UnsupportedOperationException();
}
}
}
सैक्सन परीक्षण
मैं अब सैक्सन इस
को XPahtFactory लाइन को बदलने का उपयोग कर एक ही कोड का परीक्षण किया है निम्नलिखित अद्यतनfinal XPathFactory xpathFactory = new net.sf.saxon.xpath.XPathFactoryImpl();
डिफ़ॉल्ट Xalan कार्यान्वयन के साथ के रूप में सेक्सन '// elementName' की तरह testWithNS()
बदले में सभी लाइनों *** NOT FOUND ***
बजाय सिर्फ लोगों का उपयोग करना।
यह देखते हुए कि मैं एक्सएमएल को पार्स करने के लिए एक गैर नामस्थान जागरूक दस्तावेज़ निर्माता कारखाने का उपयोग कर रहा हूं, इनमें से कोई भी xpaths क्यों काम नहीं करता है, और केवल कुछ Xalan के साथ?
XPath कार्यान्वयन में एक बग की तरह दिखता है। – obecker
मैंने सोचा था कि सोचा था कि यह किसी के लिए कुछ स्पष्ट भी हो सकता है। मैं उपरोक्त सैक्सन के साथ कोशिश करूंगा और रिपोर्ट करता हूं कि क्या होता है। –