পাইথন ব্যবহার করে একটি সাধারণ এক্সএমএল ফাইল তৈরি করা


161

আমি পাইথনে একটি সাধারণ এক্সএমএল ফাইল তৈরি করতে চাইলে আমার বিকল্পগুলি কী কী? (গ্রন্থাগার অনুযায়ী)

আমি যে এক্সএমএলটি দেখতে চাই তা দেখতে:

<root>
 <doc>
     <field1 name="blah">some value1</field1>
     <field2 name="asdfasd">some vlaue2</field2>
 </doc>

</root>

উত্তর:


310

আজকাল, সর্বাধিক জনপ্রিয় (এবং খুব সাধারণ) বিকল্পটি হল এলিমেট্রি এপিআই , যা পাইথন 2.5 এর পরে স্ট্যান্ডার্ড লাইব্রেরিতে অন্তর্ভুক্ত করা হয়েছে।

এর জন্য উপলভ্য বিকল্পগুলি হ'ল:

  • এলিমেন্টটিরি (মৌলিক, খাঁটি-পাইথন বাস্তবায়ন এলিমেট্রি। 2.5 থেকে স্ট্যান্ডার্ড লাইব্রেরির অংশ)
  • সিলেটমেন্ট ট্রি (এলিমেট্রি এর অপ্টিমাইজড সি প্রয়োগকরণ 2.5.২০ থেকে স্ট্যান্ডার্ড লাইব্রেরিতেও দেওয়া হয়েছে)
  • এলএক্সএমএল (libxML2 এর উপর ভিত্তি করে। এলিমেট্রি এপিআই পাশাপাশি এক্সপ্যাথ, সিএসএস নির্বাচক এবং আরও অনেক কিছু সরবরাহ করে)

ইনড্ড্লিব সিলেমেন্টটিরি ব্যবহার করে কীভাবে আপনার উদাহরণ নথি তৈরি করবেন তার একটি উদাহরণ এখানে রয়েছে:

import xml.etree.cElementTree as ET

root = ET.Element("root")
doc = ET.SubElement(root, "doc")

ET.SubElement(doc, "field1", name="blah").text = "some value1"
ET.SubElement(doc, "field2", name="asdfasd").text = "some vlaue2"

tree = ET.ElementTree(root)
tree.write("filename.xml")

আমি এটি পরীক্ষা করেছি এবং এটি কাজ করে, তবে আমি ধরে নিচ্ছি যে সাদা স্থানটি গুরুত্বপূর্ণ নয়। আপনার যদি "পার্টপ্রিন্ট" ইন্ডেন্টেশন দরকার হয় তবে আমাকে জানান এবং আমি কীভাবে এটি করব তা সন্ধান করব। (এটি কোনও এলএক্সএমএল-নির্দিষ্ট বিকল্প হতে পারে I আমি stdlib বাস্তবায়ন বেশি ব্যবহার করি না)

আরও পড়ার জন্য, এখানে কিছু দরকারী লিঙ্ক রয়েছে:

চূড়ান্ত নোট হিসাবে, সিলেমেন্টটি বা এলএক্সএমএল আপনার সমস্ত প্রয়োজনের জন্য দ্রুত হওয়া উচিত (উভয়ই সি সি কোডটি অনুকূলিত করা হয়েছে), তবে আপনি যদি এমন পরিস্থিতিতে থাকেন যেখানে আপনাকে প্রতিটি শেষের পারফরম্যান্সটি বের করার প্রয়োজন হয়, তখন বেঞ্চমার্কগুলি এলএক্সএমএল সাইট ইঙ্গিত করে যে:

  • এলএক্সএমএল স্পষ্টতই এক্সএমএলকে ক্রমিকায়িত করতে (জেনারেট করে) জিততে পারে
  • যথাযথ পিতামাতার ট্র্যাভারসাল বাস্তবায়নের পার্শ্ব-প্রতিক্রিয়া হিসাবে, এলএক্সএমএল পার্সিংয়ের জন্য সিলেটমেন্ট ট্রি থেকে কিছুটা ধীর।

1
@ ক্যাস্পার: আমার কাছে ম্যাক নেই তাই সমস্যার নকল করার চেষ্টা করতে পারি না। পাইথন সংস্করণটি বলুন এবং আমি এটি লিনাক্সে প্রতিলিপি করতে পারি কিনা তা আমি দেখতে পাচ্ছি।
ssokolow

4
@ অ্যানসেনসেমিকলে আপনার সত্যই নতুন প্রশ্ন জিজ্ঞাসা করা উচিত ছিল এবং তারপরে আমাকে একটি লিঙ্ক পাঠিয়েছিলেন যাতে প্রত্যেকে এটি থেকে উপকৃত হতে পারে। তবে আমি আপনাকে সঠিক দিকে নির্দেশ করব point ডোম (ডকুমেন্ট অবজেক্ট মডেল) লাইব্রেরি সর্বদা একটি ইন-মেমরি মডেল তৈরি করে যাতে আপনি পরিবর্তে একটি SAX (এক্সএমএলের জন্য সিম্পল এপিআই) প্রয়োগ করতে চান। আমি স্যাক্স বাস্তবায়ন কখনও দেখিনি তবে ইনপুট পরিবর্তে ইন-স্ট্ডলিব ব্যবহারের জন্য একটি টিউটোরিয়াল এখানে ।
ssokolow

1
@ যোনাটানসিমসন আমি সঠিক স্ট্রিংটি কীভাবে যুক্ত করব তা আমি জানি না , যেহেতু এলিমেন্ট্রি কেবলমাত্র xml_declaration=Trueকোনও এনকোডিং নির্দিষ্ট করে থাকলে তা মানবে বলে মনে হয় ... তবে, সমতুল্য আচরণ পেতে, tree.write()এই জাতীয় কল করুন : tree.write("filename.xml", xml_declaration=True, encoding='utf-8')আপনি যতক্ষণ না স্পষ্টভাবে নির্দিষ্ট করে দেন ততক্ষণ আপনি কোনও এনকোডিং ব্যবহার করতে পারবেন এক. ( asciiআপনি যদি কোনও ওয়েব সার্ভারকে সঠিকভাবে কনফিগার করার জন্য বিশ্বাস না করেন তবে 7-বিট ASCII সেট-এর বাইরে থাকা সমস্ত ইউনিকোড অক্ষরকে সত্তা-এনকোড
করাতে বাধ্য করবে

1
অন্য যে কেউ এটিকে সংশোধন vlaue2করার চেষ্টা করে তাদের কেবল একটি অনুস্মারক value2: টাইপোটি মূল প্রশ্নের অনুরোধিত এক্সএমএল আউটপুটে রয়েছে। যতক্ষণ না এটি পরিবর্তন হয়, এখানে টাইপো আসলেই সঠিক is
ssokolow

3
ডকুমেন্টেশন মতে , cElementTreeপাইথন 3.3 মধ্যে মূল্যমান হ্রাস হয়
Stevoisiak

63

Lxml গ্রন্থাগার এক্সএমএল প্রজন্মের জন্য একটি খুব সুবিধাজনক সিনট্যাক্স বলা রয়েছে ই-কারখানা । আপনার দেওয়া উদাহরণটি আমি কীভাবে করব তা এখানে:

#!/usr/bin/python
import lxml.etree
import lxml.builder    

E = lxml.builder.ElementMaker()
ROOT = E.root
DOC = E.doc
FIELD1 = E.field1
FIELD2 = E.field2

the_doc = ROOT(
        DOC(
            FIELD1('some value1', name='blah'),
            FIELD2('some value2', name='asdfasd'),
            )   
        )   

print lxml.etree.tostring(the_doc, pretty_print=True)

আউটপুট:

<root>
  <doc>
    <field1 name="blah">some value1</field1>
    <field2 name="asdfasd">some value2</field2>
  </doc>
</root>

এটি ইতিমধ্যে তৈরি নোড যুক্ত করার পক্ষেও সমর্থন করে, যেমন উপরের পরে আপনি বলতে পারেন

the_doc.append(FIELD2('another value again', name='hithere'))

3
যদি ট্যাগের নামটি পাইথন শনাক্তকারী নিয়মের সাথে মানানসই না হয় তবে আপনি ব্যবহার করতে পারেন getattr, যেমন getattr(E, "some-tag"),।
হরিদসভে

আমার জন্য প্রিন্ট lxML.etree.tostring এর কারণে অ্যাট্রিবিউটআরারের কারণ ঘটেছে: 'lxML.etree._Element' অবজেক্টটির কোনও 'এট্রি' নেই। এটি "lxML" শুরু না করেই কাজ করে। পছন্দ: etree.tostring (the_doc, চমত্কার_প্রিন্ট = সত্য)
কোডান

19

ইয়াতটাগ http://www.yattag.org/ বা https://github.com/leforestier/yattag এই জাতীয় এক্সএমএল ডকুমেন্ট (এবং এইচটিএমএল নথিও) তৈরি করতে একটি আকর্ষণীয় এপিআই সরবরাহ করে।

এটি কনটেক্সট ম্যানেজার এবং withকীওয়ার্ড ব্যবহার করছে ।

from yattag import Doc, indent

doc, tag, text = Doc().tagtext()

with tag('root'):
    with tag('doc'):
        with tag('field1', name='blah'):
            text('some value1')
        with tag('field2', name='asdfasd'):
            text('some value2')

result = indent(
    doc.getvalue(),
    indentation = ' '*4,
    newline = '\r\n'
)

print(result)

সুতরাং আপনি পাবেন:

<root>
    <doc>
        <field1 name="blah">some value1</field1>
        <field2 name="asdfasd">some value2</field2>
    </doc>
</root>

6

সহজ বিকল্পের জন্য, আমি মিনিডম সহ যাব: http://docs.python.org/library/xML.dom.minidom.html । এটি পাইথন স্ট্যান্ডার্ড লাইব্রেরিতে অন্তর্নির্মিত এবং সহজ ক্ষেত্রে এটি সহজবোধ্য।

টিউটোরিয়ালটি অনুসরণ করা এখানে বেশ সহজ: http://www.boddie.org.uk/python/XML_intro.html


6
এই উত্তরে মিনিডম ব্যবহারের একটি উদাহরণ অন্তর্ভুক্ত করা উচিত।
স্টিভোসিয়াক

4

এই জাতীয় কোনও সাধারণ এক্সএমএল কাঠামোর জন্য, আপনি একটি সম্পূর্ণ প্রস্ফুটিত এক্সএমএল মডিউলটি জড়িত করতে না চাইতে পারেন। সহজ স্ট্রাকচারের জন্য স্ট্রিং টেম্পলেট বা কিছুটা জটিল জটিল জিনিসের জন্য জিনজা বিবেচনা করুন। জিনজা আপনার নথির তালিকার অভ্যন্তরীণ এক্সএমএল তৈরি করতে ডেটা তালিকার উপরে লুপিং পরিচালনা করতে পারে। এটি কাঁচা পাইথন স্ট্রিং টেম্পলেটগুলির সাথে কিছুটা জটিল

একটি জিনজার উদাহরণের জন্য, আমার অনুরূপ প্রশ্নের উত্তর দেখুন ।

স্ট্রিং টেম্পলেটগুলি সহ আপনার এক্সএমএল তৈরির উদাহরণ এখানে।

import string
from xml.sax.saxutils import escape

inner_template = string.Template('    <field${id} name="${name}">${value}</field${id}>')

outer_template = string.Template("""<root>
 <doc>
${document_list}
 </doc>
</root>
 """)

data = [
    (1, 'foo', 'The value for the foo document'),
    (2, 'bar', 'The <value> for the <bar> document'),
]

inner_contents = [inner_template.substitute(id=id, name=name, value=escape(value)) for (id, name, value) in data]
result = outer_template.substitute(document_list='\n'.join(inner_contents))
print result

আউটপুট:

<root>
 <doc>
    <field1 name="foo">The value for the foo document</field1>
    <field2 name="bar">The &lt;value&gt; for the &lt;bar&gt; document</field2>
 </doc>
</root>

টেমপ্লেট পদ্ধতির ডাউনারটি হ'ল আপনি নিস্তার <এবং >নিখরচায় পাবেন না। আমি একটি ব্যবহার থেকে টেনে এই সমস্যাটির চারপাশে নাচলামxml.sax


1

আমি সবেমাত্র একটি এক্সএমএল জেনারেটর লেখার কাজটি শেষ করেছি, bigh_29 এর টেম্পলেটগুলির পদ্ধতি ব্যবহার করে ... আপনি খুব বেশি অবজেক্টগুলি 'পথে' না পেয়ে আপনি কী আউটপুট নিয়ে যান তা নিয়ন্ত্রণ করার একটি দুর্দান্ত উপায়।

ট্যাগ এবং মান হিসাবে, আমি দুটি অ্যারে ব্যবহার করেছি, একটি যা আউটপুট এক্সএমএলে ট্যাগ নাম এবং অবস্থান দিয়েছে এবং অন্যটি ট্যাগগুলির একই তালিকাযুক্ত একটি পরামিতি ফাইল রেফারেন্স করেছে। প্যারামিটার ফাইলটিতে অবশ্য সম্পর্কিত ইনপুট (সিএসভি) ফাইলের অবস্থান নম্বর রয়েছে যেখানে থেকে ডেটা নেওয়া হবে। এইভাবে, যদি ইনপুট ফাইল থেকে আগত ডেটার অবস্থানের কোনও পরিবর্তন হয় তবে প্রোগ্রামটি পরিবর্তন হয় না; এটি প্যারামিটার ফাইলে যথাযথ ট্যাগ থেকে ডেটা ফিল্ড পজিশনটি গতিশীলভাবে কাজ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.