JSON Toolkit

JSON ↔ YAML और XML रूपांतरण की सीमाएँ

मुख्य बात: यह दावा कि JSON, YAML का सबसेट है, केवल एक दिशा की गारंटी देता है, और XML का कोई आधिकारिक JSON मैपिंग ही नहीं है — सब कुछ परंपरा पर टिका है।

मध्यम~12 मिनट पढ़ें2026-10-30 को प्रकाशित2026-10-30 को अपडेट किया गया
JSON ↔ YAML और XML रूपांतरण की सीमाओं का कवर

सार: JSON को मध्यवर्ती प्रारूप बनाएँ: स्रोत को डेटा मॉडल में पार्स करें, फिर लक्ष्य में serialize करें; रूपांतरण से पहले तय करें कि टिप्पणियाँ, XML attribute और namespace, तथा संख्या या boolean प्रकार बचने चाहिए या नहीं।

कोई रूपांतरण पाइपलाइन काम की है या नहीं, यह इस पर नहीं टिका कि आउटपुट कितना सुंदर दिखता है, बल्कि इस पर कि आप जानते हैं उसने कितना फेंक दिया।

1. JSON और YAML: एक-तरफ़ा समावेश

YAML 1.2 विनिर्देश स्पष्ट कहता है: JSON, YAML का सबसेट है। यानी कोई भी वैध JSON वैध YAML है:

{"name": "json", "tags": ["a", "b"], "count": 3}

यह टुकड़ा JSON और YAML flow शैली दोनों है। उल्टा सत्य नहीं है।

विशेषता JSON YAML 1.2
टिप्पणियाँ ✗ ✓
Anchor और alias ✗ ✓
कई दस्तावेज़ (---) ✗ ✓
गैर-स्ट्रिंग key ✗ ✓ (1: a, true: b)
जटिल key ✗ ✓ (? [a, b])
इंडेंटेशन के प्रति संवेदनशील ✗ ✓ (tab इंडेंटेशन अस्वीकृत)
प्रकार अनुमान स्पष्ट अंतर्निहित (0o17, 0x1F, .inf)
एक-पंक्ति पठनीयता अच्छी खराब (लंबी सामग्री folding सिंटैक्स पर टिकती है)

1.1 प्रकार अनुमान सबसे बड़ा जाल है

YAML कुछ ऐसे मान जो स्ट्रिंग जैसे दिखते हैं, अन्य प्रकारों में पार्स कर देता है:

zip: 01234        # string or octal integer? the YAML 1.2 core schema treats it as a string
version: 1.10     # 1.1 (a float); the semantics are lost
country: NO       # a string in YAML 1.2; boolean false in YAML 1.1
date: 2026-10-30  # some implementations parse it as a date object

NO वाला उदाहरण बहुत लोगों को जला चुका है: YAML 1.1 parser (कुछ पुरानी लाइब्रेरी) के साथ country: NO false बन जाता है। उपाय: हर ऐसे पहचानकर्ता को उद्धरण में रखें जो "संख्या या boolean जैसा दिखता है", जैसे version: "1.10"।

1.2 Anchor, alias और कई दस्तावेज़

defaults: &defaults
  retries: 3
  timeout: 30

serviceA:
  <<: *defaults
  host: a.example.com

---
serviceB:
  <<: *defaults
  host: b.example.com

Anchor खोलकर JSON में बदलने के बाद आमतौर पर या तो दो दोहराए हुए कॉन्फ़िगरेशन object मिलते हैं, या एक array (कई दस्तावेज़ों को [{...}, {...}] बनना ही होगा)। किसी भी तरह, उल्टे रूपांतरण पर anchor बहाल नहीं होते — वह हानि अपरिहार्य है।

1.3 टिप्पणियाँ बचाने वाला रूपांतरण

अधिकांश लाइब्रेरी रूपांतरण के दौरान टिप्पणियाँ बस गिरा देती हैं। जब उन्हें रखना हो, तो yaml पैकेज का Document API इस्तेमाल करें:

import { parseDocument } from 'yaml';

const document = parseDocument(`
# Service configuration
port: 8080
`);

document.set('port', 3000);
console.log(document.toString());
// # Service configuration
// port: 3000

जाँच सरल है: यदि इस फ़ाइल को मनुष्य बार-बार संपादित करेंगे, तो "पार्स → object → serialize" का रास्ता न लें।

1.4 Round-trip संगति कैसे सत्यापित करें

/**
 * Verifies round-trip consistency for JSON → YAML → JSON.
 * @param sourceValue Original JSON value
 * @param stringify YAML serialization function
 * @param parse YAML parsing function
 * @returns Whether the two results are exactly equal
 */
function isRoundTripStable(
  sourceValue: unknown,
  stringify: (input: unknown) => string,
  parse: (input: string) => unknown,
): boolean {
  const yamlText = stringify(sourceValue);
  const restored = parse(yamlText);
  return JSON.stringify(restored) === JSON.stringify(sourceValue);
}

इसे वास्तविक डेटा पर चलाना दस्तावेज़ दस बार पढ़ने से अधिक मूल्यवान है। सुनिश्चित करें कि आपका नमूना समुच्चय कवर करे: null, खाली स्ट्रिंग, खाली array, "00", "1e5", ऋणात्मक शून्य, 2^53 से बड़े पूर्णांक, और newline वाली लंबी स्ट्रिंग।

2. JSON और XML: कोई मानक मैपिंग नहीं है

XML, JSON से बहुत पहले का है और संरचनात्मक क्षमताएँ (attribute, namespace, mixed content, DTD) कहीं अधिक मज़बूत हैं। दोनों के बीच कोई आधिकारिक मैपिंग विनिर्देश नहीं है; हर टूल एक ही काम करता है: एक परंपरा चुनो, फिर ज़्यादा न खोने की कोशिश करो।

2.1 सामान्य परंपराएँ

परंपरा निरूपण उदाहरण
Element → object key समान नाम का element फ़ील्ड बन जाता है <a>1</a> → {"a": "1"}
Attribute → @ उपसर्ग @name <a id="1"/> → {"a": {"@id": "1"}}
Text → #text जब attribute और text दोनों हों <a id="1">hi</a> → {"a": {"@id": "1", "#text": "hi"}}
दोहराया element → array दो या अधिक बार आने पर array बनता है <i>1</i><i>2</i> → {"i": ["1","2"]}
Namespace → उपसर्ग ns:tag <ns:tag/> → {"ns:tag": ...}
<order id="A1001">
  <item sku="X1" qty="2">笔记本</item>
  <item sku="X2" qty="1">钢笔</item>
</order>
{
  "order": {
    "@id": "A1001",
    "item": [
      { "@sku": "X1", "@qty": "2", "#text": "笔记本" },
      { "@sku": "X2", "@qty": "1", "#text": "钢笔" }
    ]
  }
}

2.2 पाँच अपरिहार्य हानियाँ

  1. Element का क्रम: JSON object क्रम-रहित हैं, जबकि XML element का क्रमबद्ध अनुक्रम है;
  2. Attribute बनाम बाल element: XML में उनके अर्थ अलग हैं, पर JSON में दोनों सादे फ़ील्ड बन जाते हैं;
  3. Mixed content: <p>你好 <b>世界</b> 再见</p> जैसी संरचनाएँ सादे object से व्यक्त नहीं हो सकतीं;
  4. Namespace घोषणाएँ: xmlns एक scope की धारणा है; फ़ील्ड में flatten होते ही scope खो जाता है;
  5. CDATA और entity: <![CDATA[...]]> और &amp; JSON में बस पाठ से ज़्यादा कुछ नहीं।

2.3 "एक element या array" की दुविधा

<list><item>1</item></list>

एक अकेले item के साथ xml2js डिफ़ॉल्ट रूप से object लौटाता है और array तभी लौटाता है जब दो हों। नतीजा यह है कि फ़्रंटएंड कोड को Array.isArray(x) ? x : [x] लिखना पड़ता है।

उपाय: पार्स करते समय "always array" विकल्प चालू करें, या schema के आधार पर फ़ील्ड को array प्रकार घोषित करें।

import { parseStringPromise } from 'xml2js';

const parsed = await parseStringPromise(xmlText, {
  explicitArray: true,   // return an array even for a single element
  trim: true,
  explicitRoot: false,
});

2.4 सुरक्षा अनुस्मारक

अविश्वसनीय XML पार्स करने से पहले external entity अवश्य बंद करें, वरना आप XXE (स्थानीय फ़ाइलें पढ़ना, आंतरिक नेटवर्क टटोलना) भड़का सकते हैं:

// In the Node ecosystem, DTDs and external entities are usually disabled through parser options
const parserOptions = { doctype: false, externalEntities: false };

XML → JSON रूपांतरण की केवल पहली परत है; रूपांतरण XML जो हमले की सतह लाता है, उसे खत्म नहीं करता।

3. तीनों प्रारूप कहाँ बैठते हैं

परिदृश्य सुझाया प्रारूप कारण
सार्वजनिक HTTP API JSON ब्राउज़र और हर भाषा द्वारा मूल रूप से समर्थित
हाथ से रखरखाव वाला कॉन्फ़िगरेशन YAML टिप्पणियाँ, इंडेंटेशन, पठनीयता
मज़बूत schema और namespace चाहने वाले दस्तावेज़ (SOAP, Office Open XML, SVG) XML संरचनात्मक क्षमताएँ और मौजूदा पारिस्थितिकी
परिचालन टूलिंग के साथ अंतःक्रिया (K8s, CI) YAML पारिस्थितिकी का डिफ़ॉल्ट
Persistence, कैश, लॉग JSON / JSONL सार्वभौमिक और निर्भरता-मुक्त

4. कार्यान्वयन टिप्पणियाँ

import { stringify as toYaml } from 'yaml';

/**
 * Converts a JSON value to YAML text while keeping Chinese characters unescaped.
 * @param value The JSON value to convert
 * @returns The YAML text
 */
function jsonToYaml(value: unknown): string {
  return toYaml(value, {
    indent: 2,
    lineWidth: 0,      // disable automatic wrapping so long strings are not split
    defaultStringType: 'QUOTE_DOUBLE',
  });
}

कुछ व्यावहारिक विकल्प:

  • lineWidth: 0 स्वचालित wrapping बंद करता है; वरना लंबे URL पंक्तियों में बँटकर पढ़ने में कठिन हो जाते हैं;
  • सब कुछ दोहरे उद्धरण में रखना NO और 1.10 जैसे मानों के गलत पढ़े जाने से बचाता है;
  • संवेदनशील संख्या परिशुद्धता वाले डेटा को serialize से पहले स्ट्रिंग में बदलें।

XML दिशा के लिए, एक ही मैपिंग फ़ंक्शन तय करें और "attribute उपसर्ग", "text key नाम" और "array रणनीति" को उसके signature में रखें, चारों ओर बिखेरें नहीं:

type XmlMappingOptions = {
  attributePrefix: string;
  textKey: string;
  alwaysArray: boolean;
};

const defaultMapping: XmlMappingOptions = {
  attributePrefix: '@',
  textKey: '#text',
  alwaysArray: false,
};

5. चेकलिस्ट

  • [ ] YAML में हर "संख्या/boolean जैसा" पहचानकर्ता उद्धरण में है;
  • [ ] JSON → YAML → JSON के लिए सत्यापन नमूना समुच्चय तय है और परीक्षणों से कवर है;
  • [ ] जब टिप्पणियाँ बचानी हों, object round trip के बजाय Document API इस्तेमाल होता है;
  • [ ] XML मैपिंग परंपरा लिखी हुई है और टीम एक ही पैरामीटर समुच्चय साझा करती है;
  • [ ] अविश्वसनीय XML पार्स करते समय DTD और external entity बंद हैं;
  • [ ] रूपांतरण से पहले और बाद बाइट गिनती तथा फ़ील्ड गिनती की तुलना होती है, और कोई भी असंगति अलर्ट उठाती है।

अक्सर पूछे जाने वाले प्रश्न

JSON, YAML और XML के बीच रूपांतरण की दिशा कैसे चुनूँ?

JSON को मध्यवर्ती प्रारूप बनाना पसंद करें: पहले YAML और XML को डेटा मॉडल में पार्स करें, फिर उसी मॉडल से serialize करें, पाठ दोबारा लिखने के बजाय। जब टिप्पणियाँ बचानी हों तो YAML Document API इस्तेमाल करें, और attribute या namespace की ज़रूरत से पहले एक XML मैपिंग परंपरा तय करें।

XML से JSON रूपांतरण में attribute और namespace क्यों खो जाते हैं?

JSON में attribute या namespace की कोई धारणा नहीं है, इसलिए XML attribute, उपसर्ग और namespace URI को सामान्य key में समेंटना पड़ता है, आमतौर पर @ उपसर्ग या #text node से। जैसे ही मैपिंग नियम अलग होते हैं, वही XML अलग JSON देता है और round-trip नहीं हो पाता।

JSON, YAML और XML को दीर्घकालिक दो-तरफ़ा समन्वय में रखूँ?

नहीं। टिप्पणियाँ, anchor, XML attribute और namespace प्रारूपों के पार हानिकारक हैं, और दो-तरफ़ा समन्वय में अंतर जमा होता रहता है। एक स्रोत प्रारूप चुनें और बाकी को एकबारगी निर्यात या अस्थायी दृश्य मानें।

संदर्भ

संबंधित लेख

JSON का CSV और सारणीबद्ध डेटा में तथा उससे रूपांतरण

CSV द्वि-आयामी है, JSON tree के आकार का। रूपांतरण में कठिन हिस्सा कोड नहीं — बल्कि पहले से तय करना है कि array को कैसे flatten करना है और प्रकार कैसे बचाने हैं।

शुरुआती~10 मिनट पढ़ें2026-10-30 को अपडेट किया गया

कॉन्फ़िगरेशन, fixtures और स्थानीय डेटा के लिए JSON प्रबंधित करना

कॉन्फ़िगरेशन को परतों में और सत्यापित होना चाहिए; fixtures को निर्धारक, पठनीय, और diff-योग्य होना चाहिए। यदि इन दो प्रकार की फ़ाइलों को ख़राब तरीके से प्रबंधित किया जाए, तो समस्या-समाधान की लागत लंबे समय तक ऊँची रहती है।

शुरुआती~10 मिनट पढ़ें2026-10-30 को अपडेट किया गया

JSON से YAML कमांड-लाइन: एक yq कमांड के पीछे के चार जाल

ट्यूटोरियल में सबसे ज़्यादा कॉपी की जाने वाली कमांड yq -P input.json > output.yaml, yq v4 पर वास्तव में JSON ही आउटपुट देती है। yq v4.44.6, PyYAML 6.0.3 और js-yaml से 2.39 MB नमूने पर चार माप दिखाते हैं कि आउटपुट फॉर्मैट इनपुट एक्सटेंशन तय करता है, और बैच रूपांतरण, उद्धरण, इंडेंटेशन व बड़े पूर्णांक की परिशुद्धता के सही तरीके देते हैं।

मध्यम~9 मिनट पढ़ें2026-11-03 को अपडेट किया गया