এক্সএমএল পার্স করার কৌশলসমূহ


11

আমি সবসময় এক্সএমএলকে প্রক্রিয়া করার জন্য কিছুটা জটিল দেখতে পেয়েছি। আমি এক্সএমএল পার্সার প্রয়োগের কথা বলছি না: আমি একটি স্যাক্স পার্সারের মতো বিদ্যমান স্ট্রিম-ভিত্তিক পার্সার ব্যবহার করার কথা বলছি যা এক্সএমএল নোড দ্বারা প্রসেস করে processes

হ্যাঁ, এই পার্সারগুলির জন্য বিভিন্ন এপিআইগুলি শেখা সত্যিই সহজ, তবে আমি যখনই এক্সএমএল প্রসেস করি এমন কোডটি দেখি তবে আমি সর্বদা এটি কিছুটা বিশৃঙ্খলাযুক্ত বলে মনে করি। অপরিহার্য সমস্যাটি মনে হয় যে কোনও এক্সএমএল ডকুমেন্টটি যৌক্তিকভাবে পৃথক নোডগুলিতে পৃথক করা হয় এবং তবুও ডেটা প্রকার এবং বৈশিষ্ট্যগুলি প্রায়শই আসল তথ্য থেকে আলাদা হয়, কখনও কখনও নীড়ের একাধিক স্তর দ্বারা। সুতরাং, পৃথকভাবে কোনও নির্দিষ্ট নোডের প্রক্রিয়া করার সময়, আমরা কোথায় এবং আমাদের পরবর্তী কী করা দরকার তা নির্ধারণ করতে প্রচুর অতিরিক্ত রাজ্য বজায় রাখা দরকার।

উদাহরণস্বরূপ, একটি সাধারণ এক্সএমএল ডকুমেন্ট থেকে একটি স্নিপেট দেওয়া:

<book>
  <title>Blah blah</title>
  <author>Blah blah</author>
  <price>15 USD</price>
</book>

... আমি যখন বইয়ের শিরোনামযুক্ত পাঠ্য নোডের মুখোমুখি হই তখন কীভাবে নির্ধারণ করব? মনে করুন আমাদের কাছে একটি সাধারণ এক্সএমএল পার্সার রয়েছে যা বারবারের মতো এক্সএমএল ডকুমেন্টে আমাদের পরবর্তী নোড দেয়, এটি একটি পুনরুক্তির মতো কাজ করে XMLParser.getNextNode()। আমি অনিবার্যভাবে নিজেকে নীচের মতো কোড লিখতে পাই:

boolean insideBookNode = false;
boolean insideTitleNode = false;

while (!XMLParser.finished())
{
    ....
    XMLNode n = XMLParser.getNextNode();

    if (n.type() == XMLTextNode)
    {
        if (insideBookNode && insideTitleNode)
        {
            // We have a book title, so do something with it
        }
    }
    else
    {
        if (n.type() == XMLStartTag)
        {
            if (n.name().equals("book")) insideBookNode = true
            else if (n.name().equals("title")) insideTitleNode = true;
        }
        else if (n.type() == XMLEndTag)
        {
            if (n.name().equals("book")) insideBookNode = false;
            else if (n.name().equals("title")) insideTitleNode = false;
        }
    }
}

মূলত, এক্সএমএল প্রসেসিং দ্রুত একটি বিশাল, স্টেট-মেশিন চালিত লুপে রূপান্তরিত করে, প্রচুর রাষ্ট্রীয় ভেরিয়েবলগুলি আমরা আগে খুঁজে পেয়েছি প্যারেন্ট নোডগুলি নির্দেশ করতে ব্যবহৃত হয়। অন্যথায়, সমস্ত নেস্টড ট্যাগগুলি ট্র্যাক রাখতে স্ট্যাক অবজেক্টটি বজায় রাখা দরকার। এটি দ্রুত ত্রুটি-প্রবণ এবং বজায় রাখা কঠিন হয়ে পড়ে।

আবার সমস্যাটি মনে হচ্ছে যে আমরা যে ডেটাতে আগ্রহী তা সরাসরি কোনও পৃথক নোডের সাথে সম্পর্কিত নয়। অবশ্যই, এটি হতে পারে, যদি আমরা এক্সএমএল লিখে রাখি:

<book title="Blah blah" author="blah blah" price="15 USD" />

... তবে বাস্তবে এক্সএমএল এর ব্যবহার খুব কমই হয়। বেশিরভাগ ক্ষেত্রে প্যারেন্ট নোডের শিশু হিসাবে আমাদের কাছে পাঠ্য নোড থাকে এবং পাঠ্য নোডটি কী বোঝায় তা নির্ধারণ করার জন্য আমাদের প্যারেন্ট নোডগুলি ট্র্যাক করে রাখতে হবে।

তো ... আমি কি কিছু ভুল করছি? একটি ভাল উপায় আছে কি? কোন মুহুর্তে এক্সএমএল স্ট্রিম-ভিত্তিক পার্সার ব্যবহার করা খুব জটিল হয়ে ওঠে, যাতে একটি পূর্ণ-সজ্জিত ডোম পার্সার প্রয়োজনীয় হয়? আমি অন্যান্য প্রোগ্রামারদের কাছ থেকে শুনতে চাই যে স্ট্রিম-ভিত্তিক পার্সারগুলির সাথে এক্সএমএল প্রক্রিয়াকরণ করার সময় তারা কী ধরণের আইডিয়ম ব্যবহার করে। অবশ্যই স্ট্রিম-ভিত্তিক এক্সএমএল বিশ্লেষণ সর্বদা একটি বিশাল রাজ্য মেশিনে পরিণত হবে?


2
যদি আপনার। নেট ল্যাঙ্গুয়েজ ব্যবহার করা হয় তবে আপনার লিনাক থেকে এক্সএমএল ওরফে এক্স লিঙ্কের দিকে নজর দেওয়া উচিত।
Muad'Dib

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

উত্তর:


9

আমার কাছে, প্রশ্নটি অন্য রাউন্ডে। কোন মুহূর্তে কোনও এক্সএমএল ডকুমেন্ট এত জটিল হয়ে উঠেছে যে আপনাকে DOM এর পরিবর্তে SAX ব্যবহার শুরু করতে হবে?

আমি কেবলমাত্র স্যাক্সকে খুব বড়, অনির্দিষ্ট আকারের ডেটা প্রবাহের জন্য ব্যবহার করব; বা যদি এক্সএমএলটি চাওয়ার উদ্দেশ্যে করা আচরণটি সত্যই ইভেন্ট-চালিত, এবং তাই SAX- এর মতো।

আপনি যে উদাহরণটি দিয়েছেন তা আমার কাছে খুব ডোম-মত দেখাচ্ছে।

  1. এক্সএমএল লোড করুন
  2. শিরোনাম নোড (গুলি) বের করুন এবং "তাদের সাথে কিছু করুন"।

সম্পাদনা করুন: আমি স্রোমের জন্যও স্যাক্স ব্যবহার করব যা দূষিত হতে পারে, তবে যেখানে আমি তথ্য বের করার ক্ষেত্রে সেরা অনুমান করতে চাই।


2
আমি মনে করি এটি একটি ভাল পয়েন্ট। আপনি যদি ডিওএমের জন্য খুব বড় নথির বিশ্লেষণ করছেন তবে আপনাকে XML- এর
ডিন হার্ডিং

1
+1: বিকল্পটি দেওয়া হয়েছে, আমি সর্বদা ডোমের সাথে যাব। দুর্ভাগ্যক্রমে, মনে হয় আমাদের নকশার প্রয়োজনীয়তার মধ্যে সর্বদা "কোনও আকারের নথি হ্যান্ডেল করার ক্ষমতা" এবং "অবশ্যই পারফরম্যান্ট হতে হবে" অন্তর্ভুক্ত রয়েছে, যা ডম-ভিত্তিক সমাধানগুলি প্রায়শই বাতিল করে দেয়।
টিএমএন

3
@ টিএমএন, একটি আদর্শ বিশ্বে যে প্রয়োজনীয়তাগুলি প্রথম স্থানে এক্সএমএলকে বাতিল করে দেয়।
এসকে-লজিক

1
@ টিএমএন, এটি সেই ভৌতিক প্রয়োজনীয়তার মধ্যে একটি বলে মনে হচ্ছে: "অবশ্যই আমাদের সমস্ত নথিগুলি কেবলমাত্র 100KB এর, এবং সবচেয়ে বড় আমরা দেখেছি 1MB, তবে ভবিষ্যতে কী আছে তা আপনি কখনই জানেন না, তাই আমাদের আমাদের বিকল্পগুলি খোলা রাখা উচিত এবং অসীম বড় দলিলগুলির জন্য তৈরি করুন "
পল কসাই

@ পল কসাই, আপনি কখনই জানেন না। মানে, উইকিপিডিয়াটির একটি ডাম্প 30 জিবি এক্সএমএলের মতো।
চ্যানেল 72

7

আমি খুব বেশি এক্সএমএল নিয়ে কাজ করি না, আমার মতে, সম্ভবত একটি লাইব্রেরির সাথে এক্সএমএল পার্স করার সর্বোত্তম উপায়গুলির মধ্যে একটি এক্সপথ ব্যবহার করছে।

কিছু নির্দিষ্ট নোডের জন্য গাছটিকে অনুসরণ করার পরিবর্তে আপনি এটির জন্য একটি পথ দেন। আপনার উদাহরণের ক্ষেত্রে (সিউডোকোডে) এটি এমন কিছু হবে:

বই = প্যারেন্ট.এক্সপ্যাথ ("/ বই") // এটি আপনাকে সমস্ত বইয়ের নোড দেবে
বইয়ের জন্য প্রতিটি বই
    শিরোনাম = book.xpath ("/ শিরোনাম / পাঠ্য ()")
    লেখক = book.xpath ("/ লেখক / পাঠ্য ()")
    মূল্য = book.xpath ("/ মূল্য / পাঠ্য ()")

    // ডেটা দিয়ে জিনিস

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


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

5

অবশ্যই স্ট্রিম-ভিত্তিক এক্সএমএল বিশ্লেষণ সর্বদা একটি বিশাল রাজ্য মেশিনে পরিণত হবে?

সাধারণত এটি হয়, হ্যাঁ

আমার একটি সম্পূর্ণ-সজ্জিত ডোম পার্সার ব্যবহার করার ইঙ্গিত করার জন্য যখন আমার মেমরির ফাইল হায়ারার্কির কিছু অংশ নকল করতে হবে, উদাহরণস্বরূপ নথির মধ্যে ক্রস-রেফারেন্সগুলি সমাধান করতে সক্ষম হতে হবে।


+1: ডোম দিয়ে শুরু করুন। স্যাক্স এড়িয়ে চলুন।
এস। লট

অথবা vtd-xML
vtd-xML-লেখক

4

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

আকার বা কর্মক্ষমতা সম্পর্কিত সমস্যাগুলি অন্যথায় নির্ধারিত না করা পর্যন্ত আমি সর্বদা DOM ব্যবহার করতাম।


1

পুরোপুরি ভাষা অজ্ঞেয়বাদী নয়, তবে পার্সিংয়ের কথা চিন্তা করার চেয়ে আমি সাধারণত এক্সএমএলটিকে অবজেক্টগুলিতে ডিসরিয়ালাইজ করি। আপনার প্রতি গতির সমস্যা থাকলে কেবলমাত্র সে প্রতি কৌশলগুলি পার্সিংয়ের বিষয়ে চিন্তা করার সময়।


যা পার্সিংয়ের আওতায় পড়ে। যদি না প্রশ্নে থাকা এক্সএমএল অবজেক্ট সিরিয়ালাইজেশনের আউটপুট না থাকে এবং আপনার একটি তৈরি-বিল্ড ডেসারিয়ালাইজেশন লাইব্রেরি রয়েছে। কিন্তু তারপরে এই প্রশ্নটি উপস্থিত হয় না।

অনেকগুলি ভাষা / স্ট্যাকের তৈরি বিলম্বিত deserialization লাইব্রেরি আছে।
ওয়াট বার্নেট

হ্যাঁ, তাই কি? আমার পয়েন্টগুলি এখনও ধরে আছে - বন্যের সমস্ত এক্সএমএল ফাইলগুলি এই ধরণের ফর্ম্যাটে আসে না এবং যদি আপনার কাছে এটির মতো একটি থাকে তবে আপনি এই প্রশ্নটি জিজ্ঞাসা করবেন না কারণ আপনি কেবল সেই deserialization লাইব্রেরি ব্যবহার করেন এবং নিজেই কিছু বিশ্লেষণ করবেন না , স্ট্রিম বা অন্যথায় থেকে।

0

আপনি এক্সপ্যাথ ব্যবহার করতে পারলে এটি অনেক কম জটিল হয়ে যায়। এবং। নেট ল্যান্ড লিনক থেকে এক্সএমএল অনেক কম গ্ল্যামারাস স্টাফকে বিমূর্ত করে। ( সম্পাদনা করুন - এগুলির অবশ্যই একটি ডিওএম পদ্ধতির প্রয়োজন)

মৌলিকভাবে, আপনি যদি স্ট্রিম ভিত্তিক পন্থা অবলম্বন করে থাকেন (যাতে আপনি কোনও ডিওএমের প্রয়োজন হয় এমন ভাল বিমূর্ত ব্যবহার করতে পারবেন না) আমি মনে করি এটি সর্বদা বেশ জটিল হয়ে উঠবে এবং আমি নিশ্চিত যে এর আশেপাশে কোনও উপায় নেই।


আপনি যদি এক্সপথ ব্যবহার করে থাকেন তবে আপনি ডোম ব্যবহার করছেন (যদি না আপনি এটি বাড়ির উত্সাহিত এক্সপ্যাথ মূল্যায়নকারীর সাথে ব্যবহার করেন)।
টিএমএন

হ্যাঁ, সুতরাং ডোমগুলির জন্য আবশ্যক বিমূর্ততা সম্পর্কে আমার মন্তব্য ... তবে আমি স্পষ্ট করে বলব, ধন্যবাদ!
স্টিভ

0

আপনি যদি কোনও পার্সার খুঁজে পেতে পারেন যা আপনাকে একটি পুনরুক্তি দেয়, আপনি কি এটিকে একটি লেক্সার হিসাবে বিবেচনা করার এবং কোনও স্টেট মেশিন জেনারেটর ব্যবহার করার কথা ভেবে দেখেছেন?

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