سؤال

هذه متابعة للسؤال عن تعديل 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 ...
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top