এক্সএমএল সিকোয়েন্সগুলি ফিরিয়ে দিন যেখানে কোনও বৈশিষ্ট্যে একটি নির্দিষ্ট অক্ষর থাকে না


10

নিম্নলিখিত সহজ এক্সএমএল বিবেচনা করুন:

<xml>
  <customer name="Max">
    <email address="me@you.com" />
  </customer>
  <customer name="Erik">
    <email address="erik@your-mom.com" />
  </customer>
  <customer name="Brent">
    <email address="brentcom" />
  </customer>
</xml>

আমি একটি তালিকা পেতে চান <Customer>সিকোয়েন্স যেখানে addressএর অ্যাট্রিবিউট <email>আইটেমটি নেই না একটি ধারণ @

সুতরাং, আমি দেখতে চাই যে আউটপুট:

<customer name="Brent">
  <email address="brentcom" />
</customer>

এমসিভে :

DECLARE @x XML = '<xml>
<customer name="Max"><email address="me@you.com" /></customer>
<customer name="Erik"><email address="erik@your-mom.com" /></customer>
<customer name="Brent"><email address="brentcom" /></customer>
</xml>';

এই ক্যোয়ারী:

SELECT WithValidEmail = @x.query('/xml/customer/email[contains(@address, "@")]')
    , WithInvalidEmail = @x.query('/xml/customer/email[contains(@address, "@")] = False');

রিটার্নস:

╔═══════════════════════════════════════╦══════════════════╗
            WithValidEmail              WithInvalidEmail 
╠═══════════════════════════════════════╬══════════════════╣
 <email address="me@you.com" />                          
 <email address="erik@your-mom.com" />  false            
╚═══════════════════════════════════════╩══════════════════╝

এই ক্যোয়ারী:

SELECT WithInValidEmail = @x.query('/xml/customer/email')
WHERE @x.exist('/xml/customer/email[contains(@address, "@")]') = 0;

রিটার্নস:

╔══════════════════╗
 WithInValidEmail 
╚══════════════════╝
    (no results)

WHEREউপরে ক্যোয়ারীতে দফা এক্সএমএল সমগ্র সেট দূর কারণ অন্তত একটি একক ক্রম বিদ্যমান যেখানে ইমেল ঠিকানায় একটি "@" চিহ্ন রয়েছে।

উত্তর:


11

এটি করার একটি সহজ উপায় হ'ল বৈশিষ্ট্যটির ডান পেতে nodes পদ্ধতিটি ব্যবহার addressকরা এবং আপনার @চিহ্নটি পরীক্ষা করা ।

আপনি এখন যেভাবে দেখছেন তাতে সমস্যা হ'ল এটি কেবল কোনও ইমেল ঠিকানার মধ্যে রয়েছে কিনা তা যাচাই @করে। এক্সএমএল নোডগুলি পার্স করা আপনাকে এর জন্য স্বতন্ত্র ইমেলগুলি পরীক্ষা করতে দেয়।

DECLARE @x XML
    = '<xml>
<customer name="Max"><email address="me@you.com" /></customer>
<customer name="Erik"><email address="erik@your-mom.com" /></customer>
<customer name="Brent"><email address="brentcom" /></customer>
</xml>';


SELECT x.c.value('@address', 'VARCHAR(100)') AS [email]
FROM   @x.nodes('/xml/customer/email') AS x(c)
WHERE  x.c.exist('@address[contains(., "@")]') = 0;

আপনার যদি এই জাতীয় এক্সএমএল কলাম সহ একটি আসল টেবিলটি জিজ্ঞাসা করতে হয় তবে আপনি কেবল CROSS APPLYনোডের পদ্ধতিটি পছন্দ করতেন:

SELECT x.c.value('@address', 'VARCHAR(100)') AS [email]
FROM @x_table AS xt
CROSS APPLY xt.x.nodes('/xml/customer/email') AS x(c)
WHERE  x.c.exist('@address[contains(., "@")]') = 0;

যদি আপনি <customer>...</customer>"সারি" এর জন্য সমস্ত এক্সএমএল ফিরিয়ে আনতে চান তবে আপনি অক্ষটি আবার হাঁটতে পারেন। কেবল সচেতন থাকুন যে পিছনে হাঁটা বড় এক্সএমএল ব্লকগুলির জন্য পারফরম্যান্সকে কিছুটা ওউজি করতে পারে।

SELECT x.c.query('..')
FROM @x_table AS xt
CROSS APPLY xt.x.nodes('/xml/customer/email') AS x(c)
WHERE  x.c.exist('@address[contains(., "@")]') = 0;

এটি করার আরেকটি উপায় হ'ল:

SELECT @x.query('/xml/customer[email/@address[not(contains(., "@"))]]') answer

ইমেল নোডের চারপাশে মোড়ানোর জন্য বর্গাকার বন্ধনীগুলি স্থানান্তর কার্যকরভাবে নিশ্চিত করে যে WHEREক্লজটি customerনোডের সাথে প্রয়োগ করা হয়েছে । এই এক্সকিউয়ারিটি ইংরেজিতে অনুবাদ করে দেখে মনে হচ্ছে:

আমাকে xml/customerনোডের সাথে সমস্ত নোড পান emailযার একটি addressবৈশিষ্ট্য রয়েছে যার মধ্যে @চিহ্ন নেই


4

আপনি ওহ এত কাছাকাছি ছিল। .query()ফাংশনটি ব্যবহার করে এবং containsএক্সকুয়েরি ফাংশনটি ব্যবহার করে আপনি অবশ্যই সঠিক পথে ছিলেন । আপনি যা ভুল করেছেন তা হ'ল:

  1. ফেলে = False বাইরে এর [...](অর্থ, এটা অংশ ছিল না contains()অভিব্যক্তি)
  2. Falseফাংশনের পরিবর্তে শব্দটি ব্যবহার করাfalse()
  3. /..পথের শেষে যুক্ত করে প্যারেন্ট নোডকে নির্দিষ্ট না করা (যাতে ফলাফলটি <customer>উপাদানটিকেই অন্তর্ভুক্ত করে কেবলমাত্র উপাদানকেই অন্তর্ভুক্ত করে না <email>)

এই তিনটি জিনিস সংশোধন করার ফলে নীচের এক্সকোয়ারি এক্সপ্রেশন ফলাফল হয় যা আপনি যা চান তা আপনাকে দেয়:

'/xml/customer/email[contains(@address, "@") = false()]/..'

প্রশ্ন থেকে এটিকে আপনার আসল উদাহরণটিতে রাখাই আপনাকে দেয়:

DECLARE @x XML = '<xml>
<customer name="Max"><email address="me@you.com" /></customer>
<customer name="Erik"><email address="erik@your-mom.com" /></customer>
<customer name="Brent"><email address="brentcom" /></customer>
</xml>';

SELECT
@x.query('/xml/customer/email[contains(@address, "@")]/..') AS [WithValidEmail],
@x.query('/xml/customer/email[contains(@address, "@")=false()]/..') AS [WithInvalidEmail;

এই ক্যোয়ারী দুটি এক্সএমএল ক্ষেত্রের সাথে একক সারির নিম্নলিখিত ফলাফল সেটটি প্রদান করে:

WithValidEmail                            |     WithInvalidEmail
<customer name="Max">                     |     <customer name="Brent">
  <email address="me@you.com" />          |       <email address="brentcom" />
</customer>                               |     </customer>
<customer name="Erik">                    |
  <email address="erik@your-mom.com" />   |
</customer>                               |

এটি সম্ভবত .nodes()ফাংশনটির সাথে ডকুমেন্ট ভাঙার চেয়ে বেশি দক্ষ কারণ এটি একক শটে এক্সএমএলকে বিশ্লেষণ করতে পারে এবং প্রতিটি নোডের জন্য পার্সার শুরু এবং থামানোর প্রয়োজন হয় না।

এটির মধ্যে রাখার অন্যান্য সুবিধা .query()হ'ল আপনি একক এক্সএমএল ডকুমেন্ট ফেরত পেয়েছেন। সুতরাং, আপনি যদি কোনও এক্সএমএল ডকুমেন্ট / মান পাবেন যাতে একাধিক নোডযুক্ত স্টাফ থাকে, তবে ফলাফল নোডগুলিকে আবার কোনও নথিতে পুনর্গঠন না করেই আপনি এটির একক সত্তা হিসাবে স্কেলার মান পদ্ধতির বজায় রাখতে পারেন। প্রত্যাশিত সারিগুলির প্রত্যাবর্তনের সংখ্যা পরিবর্তন না করে এটি আপনাকে একটি সাবকোয়ারি / সিটিইতে এটি ব্যবহার করতে দেয়।

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