কোনও গভীরতায় নাম অনুসারে উপাদানগুলির জন্য একটি এক্সডোকামেন্ট অনুসন্ধান করুন


143

আমার একটা XDocumentজিনিস আছে আমি লিনকিউ ব্যবহার করে যে কোনও গভীরতায় একটি নির্দিষ্ট নামের সাথে উপাদানগুলির জন্য অনুসন্ধান করতে চাই। আমি যখন ব্যবহার করি তখন আমি Descendants("element_name")কেবলমাত্র এমন উপাদানগুলি পাই যা বর্তমান স্তরের প্রত্যক্ষ শিশু। এক্সপ্যাথের "// এলিমেন্ট_নাম" এর সমতুল্য আমি যা খুঁজছি ... আমি কি কেবল ব্যবহার করব XPath, বা লিনকিউ পদ্ধতি ব্যবহার করে এটি করার কোনও উপায় আছে? ধন্যবাদ।

উত্তর:


213

বংশদ্ভুতদের একেবারে সূক্ষ্মভাবে কাজ করা উচিত। এখানে একটি উদাহরণ:

using System;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        string xml = @"
<root>
  <child id='1'/>
  <child id='2'>
    <grandchild id='3' />
    <grandchild id='4' />
  </child>
</root>";
        XDocument doc = XDocument.Parse(xml);

        foreach (XElement element in doc.Descendants("grandchild"))
        {
            Console.WriteLine(element);
        }
    }
}

ফলাফল:

<grandchild id="3" />
<grandchild id="4" />


1
কোনও এক্সএমএল ডকুমেন্টের মধ্যে কোনও উপাদানটির নাম নকল করা থাকলে আপনি কীভাবে এটি মোকাবেলা করবেন? উদাহরণস্বরূপ: যদি এক্সএমএলে <পার্ট> এর উপ উপাদানগুলির সাথে <কার> এর একটি সংগ্রহ রয়েছে এবং <পার্ট> এর উপ উপাদানগুলির সাথে <প্লেনস> এর সংগ্রহও রয়েছে এবং আপনি কেবল গাড়ির জন্য অংশগুলির একটি তালিকা চান।
pfeds

12
@ পেডফিডস: তারপরে আমি ব্যবহার করব doc.Descendants("Cars").Descendants("Part")(বা সম্ভবত .Elements("Part")তারা যদি সরাসরি শিশু ছিল were
জন স্কিটি

8
ছয় বছর এবং এখনও একটি দুর্দান্ত উদাহরণ। প্রকৃতপক্ষে, এটি এখনও এমএসডিএন ব্যাখ্যার চেয়ে অনেক বেশি সহায়ক :-)
এভিলডির

এবং এটি এখনও একটি দুষ্ট উদাহরণ, ডঃ, যেহেতু যদি "কার" না থাকে তবে উপরের কোডটি এনপিইর ফলাফল দেয়। হতে পারে।? নতুন সি # থেকে অবশেষে এটি বৈধ করে তুলবে
ডরর হারারি

3
@ ডরারহারি নোপ, কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয়নি: চেষ্টা করুন var foo = new XDocument().Descendants("Bar").Descendants("Baz"); কারণ Descendantsখালি ফিরিয়ে দেয় IEnumerable<XElement>এবং নাও null
ডেয়ারডুড

54

নাম স্থান নির্দেশ করে একটি উদাহরণ:

String TheDocumentContent =
@"
<TheNamespace:root xmlns:TheNamespace = 'http://www.w3.org/2001/XMLSchema' >
   <TheNamespace:GrandParent>
      <TheNamespace:Parent>
         <TheNamespace:Child theName = 'Fred'  />
         <TheNamespace:Child theName = 'Gabi'  />
         <TheNamespace:Child theName = 'George'/>
         <TheNamespace:Child theName = 'Grace' />
         <TheNamespace:Child theName = 'Sam'   />
      </TheNamespace:Parent>
   </TheNamespace:GrandParent>
</TheNamespace:root>
";

XDocument TheDocument = XDocument.Parse( TheDocumentContent );

//Example 1:
var TheElements1 =
from
    AnyElement
in
    TheDocument.Descendants( "{http://www.w3.org/2001/XMLSchema}Child" )
select
    AnyElement;

ResultsTxt.AppendText( TheElements1.Count().ToString() );

//Example 2:
var TheElements2 =
from
    AnyElement
in
    TheDocument.Descendants( "{http://www.w3.org/2001/XMLSchema}Child" )
where
    AnyElement.Attribute( "theName" ).Value.StartsWith( "G" )
select
    AnyElement;

foreach ( XElement CurrentElement in TheElements2 )
{
    ResultsTxt.AppendText( "\r\n" + CurrentElement.Attribute( "theName" ).Value );
}

2
তবে, যদি আমার সোর্স এক্সএমএলটির একটি নেমস্পেস না থাকে? আমি মনে করি আমি কোডে একটি যুক্ত করতে পারি (এটি সন্ধান করতে হবে), তবে কেন এটি প্রয়োজনীয়? কোনও ইভেন্টে, root.Descendants ("myTagName") আমার কোডের মধ্যে তিন বা চার স্তরের গভীর সমাহিত উপাদানগুলি খুঁজে পায় না।
EoRaptor013

2
ধন্যবাদ! আমরা ডেটা কন্ট্রাক্ট সিরিয়ালাইজেশন ব্যবহার করছি। এটি <MyClassEntries xmlns: i = " w3.org/2001/XMLSchema-instance " xmlns = " schemas.datacontract.org/2004/07/DataLayer.MyClass "> এর মতো শিরোনাম তৈরি করে এবং আমি স্ট্যাম্পড হয়েছি কেন আমি পাচ্ছি না why কোন বংশধর। আমার { স্কিমাস.ড্যাটাকন্ট্রাক্ট . org/2004/07/ ডাটালায়ার.মাইক্লাস } উপসর্গটি যুক্ত করা দরকার।
কিম

38

আপনি এটি এইভাবে করতে পারেন:

xml.Descendants().Where(p => p.Name.LocalName == "Name of the node to find")

যেখানে xmlএকটি হল XDocument

সচেতন থাকুন যে সম্পত্তিটি Nameএকটি LocalNameএবং একটি রয়েছে এমন একটি বস্তু প্রদান করে Namespace। এজন্য Name.LocalNameআপনাকে নামের সাথে তুলনা করতে চাইলে আপনাকে ব্যবহার করতে হবে ।


আমি সি # প্রকল্প ফাইল থেকে সমস্ত এম্বেডড্রোসোর্স নোড পাওয়ার চেষ্টা করছি এবং এটি কেবলমাত্র সেইভাবে কাজ করে। এক্সডোকামেন্ট ডকুমেন্ট = এক্সডোকামেন্ট.লড (সিএসপ্রোজপথ); অনুমিত <এক্সিলিমেন্ট> এম্বেডড্রোসোর্স উপাদানসমূহ = দস্তাবেজ। কাজ করে না এবং কেন বুঝতে পারি না।
ইউজিন মাকসিমভ

22

অবতরণকারীরা আপনার যা যা প্রয়োজন ঠিক তা করবে, তবে নিশ্চিত হয়ে নিন যে আপনি একটি নেমস্পেসের নামটি উপাদানটির নামের সাথে একত্রে অন্তর্ভুক্ত করেছেন। যদি আপনি এটি বাদ দেন তবে আপনি সম্ভবত একটি খালি তালিকা পাবেন।


11

এটি সম্পাদন করার দুটি উপায় রয়েছে,

  1. Linq টু XML
  2. জন্য XPath

নীচে এই পদ্ধতির ব্যবহারের নমুনা রয়েছে,

List<XElement> result = doc.Root.Element("emails").Elements("emailAddress").ToList();

আপনি যদি এক্সপথ ব্যবহার করেন তবে আপনাকে আইনিউমারেবলের সাথে কিছু হেরফের করতে হবে:

IEnumerable<XElement> mails = ((IEnumerable)doc.XPathEvaluate("/emails/emailAddress")).Cast<XElement>();

মনে রাখবেন যে

var res = doc.XPathEvaluate("/emails/emailAddress");

ফলাফল হয় নাল পয়েন্টার, বা কোন ফলাফল।


1
ঠিক যে উল্লেখ করতে XPathEvaluateহয় System.Xml.XPathনামস্থান।
তাহির হাসান

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

8

আমি XPathSelectElementsএক্সটেনশন পদ্ধতি ব্যবহার করছি যা একই XmlDocument.SelectNodesপদ্ধতিতে কাজ করে:

using System;
using System.Xml.Linq;
using System.Xml.XPath; // for XPathSelectElements

namespace testconsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument xdoc = XDocument.Parse(
                @"<root>
                    <child>
                        <name>john</name>
                    </child>
                    <child>
                        <name>fred</name>
                    </child>
                    <child>
                        <name>mark</name>
                    </child>
                 </root>");

            foreach (var childElem in xdoc.XPathSelectElements("//child"))
            {
                string childName = childElem.Element("name").Value;
                Console.WriteLine(childName);
            }
        }
    }
}

1

ফরাসিসকো গোল্ডেনস্টেইন উত্তর অনুসরণ করে, আমি একটি এক্সটেনশন পদ্ধতি লিখেছি

using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace Mediatel.Framework
{
    public static class XDocumentHelper
    {
        public static IEnumerable<XElement> DescendantElements(this XDocument xDocument, string nodeName)
        {
            return xDocument.Descendants().Where(p => p.Name.LocalName == nodeName);
        }
    }
}

0

আমরা জানি উপরেরটি সত্য। জন কখনও ভুল হয় না; বাস্তব জীবনের শুভেচ্ছা আরও কিছুটা যেতে পারে

<ota:OTA_AirAvailRQ
    xmlns:ota="http://www.opentravel.org/OTA/2003/05" EchoToken="740" Target=" Test" TimeStamp="2012-07-19T14:42:55.198Z" Version="1.1">
    <ota:OriginDestinationInformation>
        <ota:DepartureDateTime>2012-07-20T00:00:00Z</ota:DepartureDateTime>
    </ota:OriginDestinationInformation>
</ota:OTA_AirAvailRQ>

উদাহরণস্বরূপ, সাধারণত সমস্যাটি হয়, আমরা কীভাবে উপরের এক্সএমএল ডকুমেন্টে ইকো টোকেন পেতে পারি? অথবা কীভাবে নাম অ্যাট্রিবিউট দিয়ে উপাদানটি ঝাপসা করবেন।

1- নীচের মতো নাম এবং নাম দিয়ে অ্যাক্সেস করে আপনি সেগুলি খুঁজে পেতে পারেন

doc.Descendants().Where(p => p.Name.LocalName == "OTA_AirAvailRQ").Attributes("EchoToken").FirstOrDefault().Value

2- আপনি অ্যাট্রিবিউট বিষয়বস্তু মান তা খুঁজে পেতে পারেন এই এক মত


0

ক্লাসের Linqডিসেন্ডেন্ডেন্ট পদ্ধতির ভিত্তিতে সমাধানের এটি আমার বৈকল্পিকXDocument

using System;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        XDocument xml = XDocument.Parse(@"
        <root>
          <child id='1'/>
          <child id='2'>
            <subChild id='3'>
                <extChild id='5' />
                <extChild id='6' />
            </subChild>
            <subChild id='4'>
                <extChild id='7' />
            </subChild>
          </child>
        </root>");

        xml.Descendants().Where(p => p.Name.LocalName == "extChild")
                         .ToList()
                         .ForEach(e => Console.WriteLine(e));

        Console.ReadLine();
    }
}

ফলাফল:

Desendantsপদ্ধতিটি সম্পর্কে আরও বিশদের জন্য এখানে একবার দেখুন।


-1

(কোড এবং নির্দেশাবলী সি # এর জন্য এবং অন্যান্য ভাষার জন্য কিছুটা পরিবর্তন করার প্রয়োজন হতে পারে)

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

<?xml version="1.0" encoding="UTF-8"?> 
<emails>
    <emailAddress>jdoe@set.ca</emailAddress>
    <emailAddress>jsmith@hit.ca</emailAddress>
    <emailAddress>rgreen@set_ig.ca</emailAddress> 
</emails>

এখন নীচের এই কোডটি সহ (এক্সএমএল ফাইল সংস্থাগুলিতে সঞ্চিত আছে তা মনে রেখে (সংস্থাগুলির সহায়তার জন্য স্নিপেটের শেষে লিঙ্কগুলি দেখুন)) আপনি প্রতিটি ইমেল ঠিকানা "ইমেল" ট্যাগের মধ্যে পেতে পারেন।

XDocument doc = XDocument.Parse(Properties.Resources.EmailAddresses);

var emailAddresses = (from emails in doc.Descendants("emailAddress")
                      select emails.Value);

foreach (var email in emailAddresses)
{
    //Comment out if using WPF or Windows Form project
    Console.WriteLine(email.ToString());

   //Remove comment if using WPF or Windows Form project
   //MessageBox.Show(email.ToString());
}

ফলাফল

  1. jdoe@set.ca
  2. jsmith@hit.ca
  3. rgreen@set_ig.ca

দ্রষ্টব্য: কনসোল অ্যাপ্লিকেশন এবং ডাব্লুপিএফ বা উইন্ডোজ ফর্মগুলির জন্য আপনাকে অবশ্যই "System.XML.Linq ব্যবহার করে" যুক্ত করতে হবে; আপনার প্রকল্পের শীর্ষে দিকনির্দেশনা ব্যবহার করে, কনসোলের জন্য আপনাকে ব্যবহার নির্দেশিকা যুক্ত করার আগে এই নেমস্পেসে একটি রেফারেন্স যুক্ত করতে হবে। কনসোলের জন্য ডিফল্টরূপে "প্রোপার্টি ফোল্ডার" এর অধীনে কোনও রিসোর্স ফাইল থাকবে না যাতে আপনাকে ম্যানুয়ালি রিসোর্স ফাইল যুক্ত করতে হবে। নীচে এমএসডিএন নিবন্ধগুলি, এটি বিস্তারিতভাবে ব্যাখ্যা করুন।

সংস্থান সংস্থান এবং সম্পদ সম্পাদনা

কীভাবে: সংস্থানগুলি যোগ করুন বা সরান


1
এখানে অর্থ বোঝাতে চাই না, তবে আপনার উদাহরণটি নাতি নাতনিদের দেখায় না। ইমেলএড্রেস ইমেলের একটি শিশু। আমি ভাবছি যে নেমস্পেস ব্যবহার না করে অবধি ব্যবহার করার কোনও উপায় আছে কি?
সফটওয়্যারসভ্যান্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.