العمل مع مساحة الاسم أثناء تحليل XML باستخدام ElementTree
-
26-12-2019 - |
سؤال
هذه متابعة للسؤال عن تعديل XML باستخدام ElementTree
لدي الآن مساحات أسماء في ملف XML الخاص بي وحاولت فهم الإجابة على تحليل XML مع مساحة الاسم في Python عبر "ElementTree" ولها ما يلي.
ملف XML.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<grandParent>
<parent>
<child>Sam/Astronaut</child>
</parent>
</grandParent>
</project>
رمز بايثون الخاص بي بعد النظر إليه تحليل XML مع مساحة الاسم في Python عبر "ElementTree"
import xml.etree.ElementTree as ET
spaces='xmlns':'http://maven.apache.org/POM/4.0.0','schemaLocation':'http://maven.apache.org/xsd/maven-4.0.0.xsd'}
tree = ET.parse("test.xml")
a=tree.find('parent')
for b in a.findall('child', namespaces=spaces):
if b.text.strip()=='Jay/Doctor':
print "child exists"
break
else:
ET.SubElement(a,'child').text="Jay/Doctor"
tree.write("test.xml")
أحصل على الخطأ:خطأ في السمة:لا يحتوي كائن "NoneType" على سمة "findall"
المحلول
هناك مشكلتان في هذا الخط:
a=tree.find('parent')
أولاً، <parent>
ليس ابنًا مباشرًا للعنصر الجذري. <parent>
هو حفيد العنصر الجذري.يبدو الطريق إلى الوالدين /project/grandparent/parent
.للبحث عن <parent>
, ، جرب تعبير XPath */parent
أو ربما //parent
.
ثانية، <parent>
موجود في مساحة الاسم الافتراضية، لذا لن تتمكن من ذلك .find()
مع اسمها البسيط فقط.ستحتاج إلى إضافة مساحة الاسم.
فيما يلي نداءين صالحين بنفس القدر لـ tree.find()
, ، يجب على كل منها العثور على <parent>
العقدة:
a=tree.find('*/{http://maven.apache.org/POM/4.0.0}parent')
a=tree.find('*/xmlns:parent', namespaces=spaces)
التالي الدعوة إلى findall()
يحتاج إلى مؤهل مساحة الاسم:
for b in a.findall('xmlns:child', namespaces=spaces)
رابعًا، تحتاج الدعوة لإنشاء العنصر الفرعي الجديد إلى مؤهل مساحة الاسم.قد تكون هناك طريقة لاستخدام اسم الاختصار، لكن لم أتمكن من العثور عليها.اضطررت إلى استخدام الشكل الطويل للاسم.
ET.SubElement(a,'{http://maven.apache.org/POM/4.0.0}child').text="Jay/Doctor"
وأخيرًا، ستبدو مخرجات XML الخاصة بك قبيحة ما لم توفر مساحة اسم افتراضية:
tree.write('test.xml', default_namespace=spaces['xmlns'])
لا علاقة لها بجوانب XML، لقد قمت بنسخ إجابتي من السؤال السابق بشكل غير صحيح.ال else
يصطف مع for
, ، وليس مع if
:
for ...
if ...
else ...