سؤال

أريد استخدام JDOM لقراءة في ملف XML، ثم استخدم XPath لاستخراج البيانات من وثيقة JDOM. يقوم بإنشاء كائن المستند غرامة، ولكن عندما أستخدم XPath للاستعلام عن المستند للحصول على قائمة العناصر، لا أحصل على شيء.

يحتوي مستند XML الخاص بي على مساحة اسم افتراضية محددة في عنصر الجذر. الشيء المضحك هو، عندما أزيل مساحة الاسم الافتراضية، فإنه يعمل بنجاح استعلام XPath وإرجاع العناصر التي أريدها. ماذا يجب أن أفعله للحصول على استعلام XPath الخاص بي للعودة؟

XML:

<?xml version="1.0" encoding="UTF-8"?>
<collection xmlns="http://www.foo.com">
<dvd id="A">
  <title>Lord of the Rings: The Fellowship of the Ring</title>
  <length>178</length>
  <actor>Ian Holm</actor>
  <actor>Elijah Wood</actor>
  <actor>Ian McKellen</actor>
</dvd>
<dvd id="B">
  <title>The Matrix</title>
  <length>136</length>
  <actor>Keanu Reeves</actor>
  <actor>Laurence Fishburne</actor>
</dvd>
</collection>

جافا:

public static void main(String args[]) throws Exception {
    SAXBuilder builder = new SAXBuilder();
    Document d = builder.build("xpath.xml");
    XPath xpath = XPath.newInstance("collection/dvd");
    xpath.addNamespace(d.getRootElement().getNamespace());
    System.out.println(xpath.selectNodes(d));
}
هل كانت مفيدة؟

المحلول

XPath 1.0. لا يدعم مفهوم مساحة الاسم الافتراضية (XPath 2.0. هل). يفترض دائما وجود أي علامة غير مربيهة جزءا من مساحة الاسم بدون اسم.

عند استخدام XPath 1.0. تحتاج إلى شيء مثل هذا:

public static void main(String args[]) throws Exception {
    SAXBuilder builder = new SAXBuilder();
    Document d = builder.build("xpath.xml");
    XPath xpath = XPath.newInstance("x:collection/x:dvd");
    xpath.addNamespace("x", d.getRootElement().getNamespaceURI());
    System.out.println(xpath.selectNodes(d));
}

نصائح أخرى

كان لدي مشكلة مماثلة، لكن لي كان لي أن لدي مزيج من مدخلات XML، وبعضها كان لديه مساحة الاسم المحددة والبعض الآخر لم يفعل ذلك. لتبسيط مشكلتي، ركضت Snippet Jdom التالية بعد تحميل المستند.

for (Element el : doc.getRootElement().getDescendants(new ElementFilter())) {
    if (el.getNamespace() != null) el.setNamespace(null);
}

بعد إزالة جميع المسامع المسامير، كنت قادرا على استخدام بسيطة Getchild ("elname") التنقل على الطريقة أو الاستعلامات بسيطة XPath.

لن أوصي بهذه التقنية كحل عام، ولكن في حالتي كانت مفيدة بالتأكيد.

يمكنك أيضا القيام بما يلي

/*[local-name() = 'collection']/*[local-name() = 'dvd']/

هنا هي قائمة استفسارات XPath المفيدة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top