क्या सूची या मानचित्र का हिस्सा साझा करने के लिए YAML सिंटैक्स है?


94

तो, मुझे पता है कि मैं ऐसा कुछ कर सकता हूं:

sitelist: &sites
  - www.foo.com
  - www.bar.com

anotherlist: *sites

और है sitelistऔर anotherlistदोनों होते हैं www.foo.comऔर www.bar.com। हालांकि, क्या मैं वास्तव में चाहते हैं के लिए है anotherlistकरने के लिए भी शामिल www.baz.comदोहराने के लिए बिना, www.foo.comऔर www.baz.com

ऐसा करने से मुझे YAML पार्सर में एक सिंटैक्स त्रुटि मिलती है:

sitelist: &sites
  - www.foo.com
  - www.bar.com

anotherlist: *sites
  - www.baz.com

केवल एंकर और उपनाम का उपयोग करने से यह संभव नहीं लगता है कि मैं किसी अन्य स्तर के उपप्रकार को जोड़कर क्या करना चाहता हूं, जैसे:

sitelist: &sites
  - www.foo.com
  - www.bar.com

anotherlist:
  - *sites
  - www.baz.com

जिसका अर्थ है कि इस YAML फ़ाइल के उपभोक्ता को इसके बारे में पता होना चाहिए।

वहाँ इस तरह से कुछ करने का एक शुद्ध YAML तरीका है? या क्या मुझे कुछ पोस्ट- YAML प्रसंस्करण का उपयोग करना होगा, जैसे कि चर प्रतिस्थापन या कुछ प्रकार के उपप्रकार के ऑटो-लिफ्टिंग को लागू करना? मैं पहले से ही कुछ अन्य उपयोग के मामलों को संभालने के लिए उस तरह की पोस्ट-प्रोसेसिंग कर रहा हूं, इसलिए मैं इससे पूरी तरह से प्रभावित नहीं हूं। लेकिन मेरी YAML फाइलें इंसानों द्वारा लिखी जाने वाली हैं, न कि मशीन द्वारा बनाई गई हैं, इसलिए मैं उन नियमों की संख्या को कम करना चाहूंगा जिन्हें मेरे उपयोगकर्ताओं द्वारा मानक YAML सिंटैक्स के शीर्ष पर याद किए जाने की आवश्यकता है।

मैं भी नक्शे के साथ अनुरूप काम करने में सक्षम होना चाहते हैं:

namedsites: &sites
  Foo: www.foo.com
  Bar: www.bar.com

moresites: *sites
  Baz: www.baz.com

मैं YAML कल्पना के माध्यम से एक खोज की है , और कुछ भी नहीं मिल सकता है, इसलिए मुझे संदेह है कि जवाब सिर्फ "नहीं, आप ऐसा नहीं कर सकते"। लेकिन अगर किसी के पास कोई विचार है जो महान होगा।


संपादित करें: चूंकि कोई उत्तर नहीं है, इसलिए मैं मान रहा हूं कि किसी ने कुछ भी नहीं देखा है जो कि मैं YAML की कल्पना में नहीं आया हूं और यह कि YAML परत पर नहीं किया जा सकता है। इसलिए मैं इस सवाल को हल करने के लिए YAML को पोस्ट-प्रोसेसिंग के लिए विचार करने के लिए सवाल खोल रहा हूं, अगर किसी को भविष्य में यह सवाल मिलता है।


नोट: इस मुद्दे को YAML में एंकर और उपनाम के मानक उपयोग के साथ भी संबोधित किया जा सकता है। यह भी देखें: YAML सरणियों का विलय कैसे करें?
dreftymac

जवाबों:


53

मर्ज कुंजी प्रकार संभवतः वह है जो आप चाहते हैं। यह <<मर्ज को इंगित करने के लिए एक विशेष मैपिंग कुंजी का उपयोग करता है , जिससे एक मैपिंग के लिए एक उपनाम (या ऐसे उपनामों का एक क्रम) को एक एकल मानचित्रण में विलय करने के लिए एक प्रारंभिक के रूप में उपयोग किया जा सकता है। इसके अतिरिक्त, आप अभी भी स्पष्ट रूप से मानों को ओवरराइड कर सकते हैं, या अधिक जोड़ सकते हैं जो मर्ज सूची में मौजूद नहीं थे।

यह ध्यान रखना महत्वपूर्ण है कि यह मैपिंग के साथ काम करता है, न कि आपके पहले उदाहरण के रूप में अनुक्रम। जब आप इसके बारे में सोचते हैं तो यह समझ में आता है, और आपका उदाहरण ऐसा लगता है कि इसे वैसे भी अनुक्रमिक होने की आवश्यकता नहीं है। बस अपने अनुक्रम मानों को मैपिंग कुंजियों में बदलते हुए चाल को करना चाहिए, जैसा कि निम्नलिखित (अप्रयुक्त) उदाहरण में है:

sitelist: &sites
  ? www.foo.com  # "www.foo.com" is the key, the value is null
  ? www.bar.com

anotherlist:
  << : *sites    # merge *sites into this mapping
  ? www.baz.com  # add extra stuff

ध्यान देने योग्य कुछ बातें। सबसे पहले, चूंकि <<एक कुंजी है, यह केवल नोड के अनुसार एक बार निर्दिष्ट किया जा सकता है। दूसरे, जब मूल्य के रूप में एक अनुक्रम का उपयोग करते हैं, तो आदेश महत्वपूर्ण होता है। यह यहां उदाहरण में कोई फर्क नहीं पड़ता, क्योंकि संबंधित मूल्य नहीं हैं, लेकिन यह जागरूक होने के लायक है।


आह आपका धन्यवाद! यह काफी मददगार है। यह एक शर्म की बात है कि यह दृश्यों के लिए काम नहीं करता है, हालांकि। आप सही हैं कि इस उदाहरण के लिए आदेश महत्वपूर्ण नहीं है; मेरे पास वैचारिक रूप से एक सेट है, लेकिन मैपिंग की तुलना में यह अनुक्रम के अधिक निकट है। और मैं इस मामले से बाहर निकलने की संरचना (यही कारण है कि मैं सिर्फ अपनी संरचनाओं को मर्ज करने के लिए घोंसले की एक और परत जोड़ना नहीं चाहता था), इसलिए एक मैपिंग जिसके लिए मुझे (सभी अशक्त) मानों की अनदेखी करने की आवश्यकता है 'सच में काम नहीं।
बेन

3
मुझे वर्तमान आधिकारिक YAML कल्पना में कुछ भी दिखाई नहीं देता है: yaml.org/spec/1.2/spec.html । उस पृष्ठ में "मर्ज" शब्द नहीं है, न ही पाठ "<<", और न ही वाक्यांश "कुंजी प्रकार"। << सिंटैक्स हालांकि पायथन याम्ल पैकेज में काम करता है। क्या आप जानते हैं कि मैं इस प्रकार की अतिरिक्त सुविधाओं के बारे में और कहाँ पता लगा सकता हूँ?
बेन

1
यह सीधे कल्पना में नहीं है, यह टैग रिपॉजिटरी में वर्णित है। अन्य स्कीमाओं में एक सामान्य विवरण और लिंक होता है। मर्ज कीज़ के अलावा, सेट और ऑर्डर किए गए सेट भी हैं; हालाँकि, YAML एक प्रकार की मैपिंग के रूप में सेट को मानता है (उदाहरण के लिए, उपरोक्त उदाहरण को एक सेट के रूप में लागू किया जा सकता है)। क्या आपकी भाषा आपको परिणामी मैपिंग में मानों के साथ चाबियाँ स्वैप करने की अनुमति देती है? यहां तक ​​कि अगर आपको खुद को लागू करना है, तो मुझे लगता है कि यह क्लीनर होगा; आप कम से कम सभी डेटा पहले से ही एक साथ समूहीकृत होंगे, और आपका YAML मानक होगा।
किट्टमॉन

सेट हालांकि मैपिंग नहीं हैं; मानचित्रण कुंजी-मूल्य संघों का एक समूह है। जब मैं yaml.load(...)पायथन में होता हूं, तो मुझे एक YAML मैपिंग के प्रतिनिधित्व के रूप में एक शब्दकोश मिलता है। हां, यह एक प्रक्रिया में पोस्ट-प्रोसेस करना आसान है, लेकिन मुझे यह जानना होगा कि ऐसा हुआ है (और कॉन्फिग फाइल को पढ़ते / लिखते समय शब्दार्थ जटिलता बहुत अधिक है यदि नियम "सेट को शून्य मानों वाले नक्शे के रूप में लिखा गया है" )। यह देखते हुए कि मुझे yaml.load(...)परिणामी डेटा के बीच एक पोस्ट-प्रोसेसिंग की आवश्यकता है <<या नहीं MERGE, चाहे मैं उपयोग करूं या , मैं शायद साथ रहूंगा MERGE(जो मैंने पहले ही लागू किया है)।
बेन

2
हाँ, मुझे लगता है कि !!setकाम करता है। हालांकि बहुत अस्पष्ट बॉयलरप्लेट। इन फ़ाइलों को मानव पठनीय / लिखने योग्य बनाया जाता है, जो जरूरी नहीं कि YAML विशेषज्ञ हों। लोग अपनी सूचियों को YAML सूचियों के रूप में लिखने जा रहे हैं, फिर उन्हें मर्ज करना चाहते हैं और पूरी चीज़ को एक सेट में बदलना है और इसे एक सेट के रूप में स्पष्ट रूप से टैग करना याद रखें ... मेरे पास अन्य मानकीकृत पोस्ट के एक जोड़े हैं- MERGEवैसे भी चीजों को प्रोसेस करना । यद्यपि कि आपकी इस सहायता के लिए धन्यवाद!
बेन

16

जैसा कि पिछले जवाबों में बताया गया है, यमलोक में सूचियों का विस्तार करने के लिए कोई अंतर्निहित समर्थन नहीं है। मैं खुद इसे लागू करने का एक और तरीका पेश कर रहा हूं। इस पर विचार करो:

defaults: &defaults
  sites:
    - www.foo.com
    - www.bar.com

setup1:
  <<: *defaults
  sites+:
    - www.baz.com

इसमें संसाधित किया जाएगा:

defaults:
  sites:
    - www.foo.com
    - www.bar.com

setup1:
  sites:
    - www.foo.com
    - www.bar.com
    - www.baz.com

यह विचार एक '+' के साथ समाप्त होने वाली कुंजी की सामग्री को '+' के बिना संबंधित कुंजी में विलय करने का है। मैंने इसे पायथन में लागू किया और यहां प्रकाशित किया ।

का आनंद लें!


2
नोट: इस मुद्दे को YAML में एंकर और उपनाम के मानक उपयोग के साथ भी संबोधित किया जा सकता है। यह भी देखें: YAML सरणियों का विलय कैसे करें?
dreftymac

11
इसका मतलब यह है कि यह दृष्टिकोण केवल एक अलग उपकरण के साथ काम करता है जो विलय करता है sitesऔर sites+। मेरा मतलब है कि एक उपकरण जिसे उपयोगकर्ता द्वारा कार्यान्वित किया जाना है क्योंकि यह एक डिफ़ॉल्ट yamlव्यवहार नहीं है ?
स्टेन ०

7

(मेरे अपने प्रश्न का उत्तर देने के मामले में, जो समाधान मैं उपयोग कर रहा हूं, वह भविष्य में इसके लिए खोज करने वाले किसी व्यक्ति के लिए उपयोगी है)

ऐसा करने के लिए कोई शुद्ध-यमर्ल मार्ग नहीं होने के कारण, मैं इसे एक "वाक्यविन्यास परिवर्तन" के रूप में लागू करने जा रहा हूं, जो कि लामल पार्सर और कोड के बीच बैठा है जो वास्तव में कॉन्फ़िगरेशन फ़ाइल का उपयोग करता है। इसलिए मेरे मूल आवेदन में किसी भी मानव-अनुकूल अतिरेक-परहेज के उपायों के बारे में चिंता करने की ज़रूरत नहीं है, और परिणामी संरचनाओं पर सीधे कार्य कर सकते हैं।

मैं जिस संरचना का उपयोग करने जा रहा हूं वह इस प्रकार है:

foo:
  MERGE:
    - - a
      - b
      - c
    - - 1
      - 2
      - 3

जिसे इसके बराबर में बदल दिया जाएगा:

foo:
  - a
  - b
  - c
  - 1
  - 2
  - 3

या, नक्शे के साथ:

foo:
  MERGE:
    - fork: a
      spoon: b
      knife: c
    - cup: 1
      mug: 2
      glass: 3

में तब्दील हो जाएगा:

foo:
  fork: a
  spoon: b
  knife: c
  cup: 1
  mug: 2
  glass: 3

अधिक औपचारिक रूप से, एक फ़ाइल से देशी वस्तुओं को प्राप्त करने के लिए YAML पार्सर को कॉल करने के बाद, लेकिन बाकी की वस्तुओं को पास करने से पहले, मेरा आवेदन एकल कुंजी वाले मैपिंग की तलाश में ऑब्जेक्ट ग्राफ को चलाएगा MERGE। संबंधित मूल्य MERGEया तो सूचियों की सूची, या मानचित्रों की सूची होनी चाहिए; किसी भी अन्य उपप्रकार एक त्रुटि है।

लिस्ट-ऑफ-लिस्ट मामले में, पूरे नक्शे MERGEको बच्चे की सूचियों द्वारा बदल दिया जाएगा , जो एक साथ दिखाई देने वाले क्रम में।

सूची के नक्शे के मामले में, पूरे मानचित्र वाले नक्शे को MERGEएक ही नक्शे से बदल दिया जाएगा जिसमें सभी मुख्य / मूल्य जोड़े बच्चे के नक्शे में होंगे। जहां कुंजियों में ओवरलैप होता है, MERGEसूची में अंतिम बार होने वाले चाइल्ड मैप से मूल्य का उपयोग किया जाएगा।

ऊपर दिए गए उदाहरण उतने उपयोगी नहीं हैं, क्योंकि आप केवल उस संरचना को लिख सकते हैं जिसे आप सीधे चाहते थे। इसकी संभावना अधिक है:

foo:
  MERGE:
    - *salt
    - *pepper

आपको एक सूची या मानचित्र बनाने की अनुमति है जिसमें नोड्स में सब कुछ है saltऔर pepperकहीं और उपयोग किया जा रहा है।

(मैं उस foo:बाहरी मानचित्र को यह दिखाने के लिए देता हूं कि इसकी मैपिंग में एकमात्र कुंजी MERGEहोनी चाहिए , जिसका अर्थ है कि शीर्ष-स्तरीय नाम के रूप में प्रकट नहीं हो सकता है जब तक कि कोई अन्य शीर्ष स्तर के नाम न हों)MERGE


6

यहां दो उत्तरों में से कुछ स्पष्ट करने के लिए, यह सीधे सूची के लिए YAML में समर्थित नहीं है (लेकिन यह शब्दकोशों के लिए समर्थित है, kittemon का उत्तर देखें)।


नोट: इस मुद्दे को YAML में एंकर और उपनाम के मानक उपयोग के साथ भी संबोधित किया जा सकता है। यह भी देखें: YAML सरणियों का विलय कैसे करें?
dreftymac

5

किट्टमन के उत्तर को बंद करने के लिए, ध्यान दें कि आप वैकल्पिक सिंटैक्स का उपयोग करके शून्य मानों के साथ मैपिंग बना सकते हैं

foo:
    << : myanchor
    bar:
    baz:

सुझाए गए सिंटैक्स के बजाय

foo:
    << : myanchor
    ? bar
    ? baz

किट्टम ​​के सुझाव की तरह, यह आपको मानचित्रण के भीतर एंकरों के संदर्भों का उपयोग करने और अनुक्रम मुद्दे से बचने की अनुमति देगा। मैंने पाया कि सिम्फनी यमल घटक v2.4.4 को ? barसिंटैक्स में फिर से शामिल नहीं करने की खोज के बाद मुझे खुद को ऐसा करने की आवश्यकता थी ।


कैसा myanchorदिखता है?
एसएससी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.