قم بتحويل صفيف YAML إلى قائمة Java باستخدام SnakeYAML

المُقدّمة

YAML هي واحدة من أكثر لغات تسلسل البيانات شيوعًا بعد JSON. لذلك ، يطلق عليه أحيانًا اسم ملف صارم مجاميع من JSON. لقد تم تصميمه للتفاعل البشري وقابلية القراءة منذ البداية ، ومن ثم فهو معروف ببساطته. تم تصميمه مع مراعاة المرونة وسهولة الوصول ، لذلك فهو يعمل مع جميع لغات البرمجة الحديثة وتنسيق قوي لكتابة ملفات التكوين. يتم استخدامه أيضًا لاستمرار البيانات والمراسلة عبر الإنترنت ومشاركة البيانات عبر اللغات والعديد من الخيارات الأخرى.

بدأ YAML في عام 2001 وكان يطلق عليه "لغة ترميزية أخرى" فى ذلك التوقيت. ولكن لاحقًا تم تسجيلها كعلامة تجارية "YAML ليست لغة ترميزية". الهيكل الأساسي لملف YAML هو ملف رسم خريطة. يُعرف أيضًا باسم القاموس أو التجزئة (الخريطة) أو ببساطة يعتمد على الكائن بناءً على لغة البرمجة التي نختار استخدامها.

تُستخدم المسافات البادئة والمسافة البادئة في ملفات YAML للإشارة إلى التداخل.

ملاحظات: يمكن استخدام المسافات فقط للمسافات البادئة في ملفات YAML ؛ أحرف الجدولة غير مسموح بها. طالما أن المسافة البادئة تتم باستمرار ، فلا يهم عدد المساحات المستخدمة.

بناء جملة YAML

يستخدم تنسيق YAML بشكل أساسي ثلاثة أنواع من العقد:

  • الخرائط / القواميسفي ممارسة اللياقة البدنية: رسم خريطة العقدة عبارة عن مجموعة غير مرتبة من المفتاح / القيمة العقدة أزواج، بشرط أن يكون كل مفتاح مميزًا. لا مزيد من القيود المفروضة على العقد من قبل YAML.
  • المصفوفات / القوائم: حدث مجموعة محتوى العقدة عبارة عن مجموعة مرتبة من صفر أو أكثر من العقد. قد يتضمن التسلسل نفس العقدة أكثر من مرة ، على وجه الخصوص. قد تحتوي حتى على نفسها.
  • الحرفيين (سلاسل ، أرقام ، منطقية ، إلخ.): تسلسل من صفر أو أكثر أحرف Unicode يمكن استخدامها لتمثيل البيانات غير الشفافة التي تشكل ملف العددية محتوى العقدة.

في هذه المقالة ، سنلقي نظرة خاصة على تحويل محتوى مصفوفة YAML إلى قائمة في Java. هناك الكثير من المكتبات مفتوحة المصدر المتاحة ولكن الأكثر شهرة من بينها جاكسون و ثعبان. في هذا الدليل ، سوف نستخدم SnakeYaml كمكتبتنا لتحليل محتوى YAML.

ثعبان

ثعبان عبارة عن حزمة تحليل YAML توفر واجهة برمجة تطبيقات عالية المستوى لتسلسل مستندات YAML وإلغاء التسلسل. نقطة دخول SnakeYAML هي ملف Yaml صف دراسي. يمكن تحميل المستندات أو ملفات YAML باستخدام load() طريقة أو دفعة واحدة عبر loadAll() طريقة. تأخذ الأساليب بيانات YAML الأصلية في شكل كائنات سلسلة أيضًا InputStreams، وهو نوع ملف نموذجي يجب مواجهته.

نظرا إلى : بنية فطرية لملفات YAML ، يعمل SnakeYAML بشكل جيد مع ملفات خرائط جافا، ولكن يمكننا أيضًا استخدام ملفات فريدة كائنات جافا.

لتضمين المكتبة في مشروعنا ، أضف التبعية التالية إلى pom.xml ملف:

<dependencies>
    <dependency>
        <groupId>org.yaml</groupId>
        <artifactId>snakeyaml</artifactId>
        <version>1.33</version>
    </dependency>
</dependencies>

أو ، إذا كنت تستخدم Gradle:

compile group: 'org.yaml', name: 'snakeyaml', version: '1.33'

قراءة صفيف YAML بسيط

لنبدأ بسرعة بقراءة مصفوفة بسيطة من ملف YAML. ضع في اعتبارك أن لدينا ملف yaml بالبيانات التالية في مجلد موارد مشروع Java الخاص بنا:

- One
- Two
- Three
- Four

ثم يمكننا تحميل محتوى الملف كملف InputStream. بعد ذلك ، سنقوم ببناء ملف Yaml المثيل الذي سيعمل بعد ذلك كنقطة دخول للوصول إلى المكتبة وكائن لتمثيل محتويات ملف YAML برمجيًا. ال load() طريقة تسمح لنا بقراءة وتحليل أي InputStream مع بيانات YAML الصالحة:

public void readYamlWithArray() {
    InputStream inputStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream("number.yml");
    Yaml yaml = new Yaml();
    List data = yaml.load(inputStream);
    System.out.println(data);
 }

ستعيد الطريقة ملف Java List من بيانات السلسلة. إذا قمنا بطباعة ملف data ثم ستعطي النتيجة التالية:

[One, Two, Three, Four]

قراءة مصفوفة YAML المجمعة

نود أحيانًا تحديد مجموعة من المحتويات مقابل مفتاح معين. وهذا ما يسمى تجميع المصفوفات في عقدة خريطة YAML. عينة YAML من هذا النوع تبدو كما يلي:

languages:
  - Java
  - JavaScript
  - Python
  - Golang
  - Perl
  - Shell
  - Scala

يمكن اعتبار هذا جافا Map تحتوي على : حيث تكون القيمة مجموعة. لذلك سيتم تحميل البيانات كملفات InputStream كما حددنا أعلاه. لكن ال data يجب تعريفه على أنه Map of List of Strings:

public void readYamlWithArrayGroup() {
    InputStream inputStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream("language.yml");
    Yaml yaml = new Yaml();
    Map<String, List> data = yaml.load(inputStream);
    System.out.println(data);
    
    data.values()
            .stream()
            .collect(Collectors.toList())
            .get(0)
            .forEach(System.out::println);
}

الآن إذا قرأنا data، سيبدو شيء هكذا:

{languages=[Java, JavaScript, Python, Golang, Perl, Shell, Scala]}
Java
JavaScript
Python
Golang
Perl
Shell
Scala

قراءة صفيف متعدد الأسطر YAML

أحيانًا نصادف ملف YAML يحتوي على بيانات تحتوي على مصفوفة من المصفوفات. على سبيل المثال ، نقوم بتجميع الدورات التدريبية وتمثيلها كمصفوفة من المصفوفات كما يلي:

courses:
  - - C
    - Java
    - Data Structures
    - Algorithms
  - - Big Data
    - Spark
    - Kafka
    - Machine Learning

يمكن تحليل هذا على أنه جافا Map of List of List of String. يمكننا تحميل ملف InputStream كما فعلنا سابقًا. ولكن سيتم تحميل البيانات على النحو التالي:

تحقق من دليلنا العملي العملي لتعلم Git ، مع أفضل الممارسات ، والمعايير المقبولة في الصناعة ، وورقة الغش المضمنة. توقف عن أوامر Googling Git وفي الواقع تعلم ذلك!

public void readYamlWithMultiLineArrayGroup() {
    InputStream inputStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream("courses.yml");
    Yaml yaml = new Yaml();
    
    Map<String, List<List>> data = yaml.load(inputStream);
    System.out.println(data);
    
    System.out.println("First Array Group:");
    data.values()
            .stream()
            .collect(Collectors.toList())
            .get(0)
            .get(0)
            .forEach(System.out::println);
    
    System.out.println("nSecond Array Group:");
    data.values()
            .stream()
            .collect(Collectors.toList())
            .get(0)
            .get(1)
            .forEach(System.out::println);
}

لذلك إذا قمنا بطباعة ملف data، سيبدو كما يلي:

{courses=[[C, Java, Data Structures, Algorithms], [Big Data, Spark, Kafka, Machine Learning]]}

First Array Group:
C
Java
Data Structures
Algorithms

Second Array Group:
Big Data
Spark
Kafka
Machine Learning

قراءة محتوى YAML المعقد المتداخل مثل Java Bean

لقد رأينا كيف يمكننا التعامل مع محتوى نوع المصفوفة بشكل منفصل ، ولكن مع ملفات YAML المتداخلة المعقدة - من الصعب تحليل خريطة الخرائط مع قوائم القوائم بشكل حدسي ومن الصعب التعامل معها. حتى في المثال الأخير حيث كان لدينا قائمتان متداخلتان فقط - التعامل معهما كقوائم يصبح مطولًا إلى حد ما.

في هذه الحالات ، من الأفضل إنشاء POJO يمكن تعيينه لبيانات YAML المتداخلة ، فلنقم أولاً بإنشاء نموذج YAML يحتوي على المحتوى المتداخل لموقع الويب:

website: stackabuse
skills:
  - python
  - javascript
  - java
  - unix
  - machine learning
  - web development
tutorials:
  - graphs:
      name: Graphs in Python - Theory and Implementation
      tags:
        - python
        - data structures
        - algorithm
      contributors:
        - David Landup
        - Dimitrije Stamenic
        - Jovana Ninkovic
      last_updated: June 2022
  - git:
      name: Git Essentials - Developer's Guide to Git
      tags:
        - git
      contributors:
        - David Landup
        - François Dupire
        - Jovana Ninkovic
      last_updated: April 2022
  - deep learning:
      name: Practical Deep Learning for Computer Vision with Python
      tags:
        - python
        - machine learning
        - tensorflow
        - computer vision
      contributors:
        - David Landup
        - Jovana Ninkovic
      last_updated: October 2022
published: true

نحتاج إلى تحديد فئة Java الأصل WebsiteContent التي سوف تتكون من List المهارات و أ List of Map من البرامج التعليمية التي ستحتوي مرة أخرى على قوائم العلامات والمساهمين:

public class WebsiteContent {
    private String website;
    private List skills;
    private List<Map> tutorials;
    private Boolean published;

    

    @Override
    public String toString() {
        return "WebsiteContent{" +
                "website='" + website + ''' +
                ", skills=" + skills +
                ", tutorials=" + tutorials +
                ", published=" + published +
                '}';
    }
}
public class Tutorial {

    private String name;
    private List tags;
    private List contributors;
    private String lastUpdated;

    

    @Override
    public String toString() {
        return "Tutorial{" +
                "name='" + name + ''' +
                ", tags=" + tags +
                ", contributors=" + contributors +
                ", lastUpdated='" + lastUpdated + ''' +
                '}';
    }
}

يمكننا الآن تحميل البيانات مرة أخرى من الملف كملف InputStream كما فعلنا سابقًا. بعد ذلك عندما نقوم بإنشاء Yaml كائن فئة ، نحتاج إلى تحديد نوع البيانات الذي نريد إرسال البيانات إليه. ال new Constructor(WebsiteContent.class) تخبر SnakeYAML بقراءة البيانات من ملف YAML وتعيينها إلى ملف WebsiteContent موضوع.

التعيين واضح ومباشر ويجب أن تتطابق أسماء سمات الكائن لدينا مع أسماء سمات YAML.

public void readYamlAsBeanWithNestedArrays(){
    
    InputStream inputStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream("website_content.yml");
            
    
    Yaml yaml = new Yaml(new Constructor(WebsiteContent.class));
    WebsiteContent data = yaml.load(inputStream);
    
    
    System.out.println(data);
    System.out.println("nList of Skills: ");
    data.getSkills().stream().forEach(System.out::println);
    System.out.println("nList of Tutorials: ");
    data.getTutorials().stream().forEach(System.out::println);
}

أخيرًا ، عندما نطبع ملف data، سيبدو كما يلي:

WebsiteContent{website='stackabuse', skills=[python, javascript, java, unix, machine learning, web development], tutorials=[{graphs={name=Graphs in Python - Theory and Implementation, tags=[python, data structures, algorithm], contributors=[David Landup, Dimitrije Stamenic, Jovana Ninkovic], last_updated=June 2022}}, {git={name=Git Essentials - Developer's Guide to Git, tags=[git], contributors=[David Landup, François Dupire, Jovana Ninkovic], last_updated=April 2022}}, {deep learning={name=Practical Deep Learning for Computer Vision with Python, tags=[python, machine learning, tensorflow, computer vision], contributors=[David Landup, Jovana Ninkovic], last_updated=October 2022}}], published=true}

List of Skills: 
python
javascript
java
unix
machine learning
web development

List of Tutorials: 
{graphs={name=Graphs in Python - Theory and Implementation, tags=[python, data structures, algorithm], contributors=[David Landup, Dimitrije Stamenic, Jovana Ninkovic], last_updated=June 2022}}
{git={name=Git Essentials - Developer's Guide to Git, tags=[git], contributors=[David Landup, François Dupire, Jovana Ninkovic], last_updated=April 2022}}
{deep learning={name=Practical Deep Learning for Computer Vision with Python, tags=[python, machine learning, tensorflow, computer vision], contributors=[David Landup, Jovana Ninkovic], last_updated=October 2022}}

كما نرى ، نجح SnakeYaml في تحليل وتحويل ملف WebsiteContent وجوه والاحتفاظ بالميراث والارتباط به Tutorial كائن سليم.

وفي الختام

نظرًا لاستخدام ملفات YAML على نطاق واسع لـ DevOps والبيانات ذات الصلة بالتكوين ، فمن المفيد جدًا تحليل البيانات ومعالجتها باستخدام التعليمات البرمجية.

يتيح لنا SnakeYAML إدارة ملفات YAML في مشروع Java الخاص بنا بسهولة ، ولا يتطلب سوى القليل من التعليمات البرمجية لتحميل ملفات YAML في مشروعنا أو كتابة البيانات في ملفات YAML. بالإضافة إلى ذلك ، يقدم SnakeYAML خيارات تنسيق حتى تتمكن من تعديلها وتخصيصها لتناسب احتياجاتنا.

الطابع الزمني:

اكثر من ستاكابوز