แปลง YAML Array เป็นรายการ Java ด้วย SnakeYAML

บทนำ

ย.ม เป็นหนึ่งในภาษาซีเรียลไลซ์เซชั่นข้อมูลที่นิยมมากที่สุดหลังจาก JSON. จึงเรียกกันว่า เข้มงวด ซุปเปอร์เซ็ต ของ JSON ได้รับการออกแบบมาสำหรับการโต้ตอบของมนุษย์และความสามารถในการอ่านได้ตั้งแต่เริ่มต้น ดังนั้นจึงเป็นที่รู้จักในด้านความเรียบง่าย ได้รับการออกแบบโดยคำนึงถึงความยืดหยุ่นและความสามารถในการเข้าถึง จึงทำงานร่วมกับภาษาโปรแกรมสมัยใหม่ทั้งหมดและรูปแบบที่มีประสิทธิภาพสำหรับการเขียนไฟล์การกำหนดค่า นอกจากนี้ยังใช้สำหรับการคงอยู่ของข้อมูล การส่งข้อความทางอินเทอร์เน็ต การแบ่งปันข้อมูลข้ามภาษา และตัวเลือกอื่นๆ อีกมากมาย

YAML เริ่มต้นในปี 2001 และถูกเรียกว่า “อีกภาษามาร์กอัป" ในเวลานั้น. แต่ต่อมาได้ขึ้นเครื่องหมายการค้าว่า “YAML ไม่ใช่ภาษามาร์กอัป“. โครงสร้างพื้นฐานของไฟล์ YAML คือ a แผนที่. มันยังเป็นที่รู้จักกันในนามพจนานุกรม แฮช (แผนที่) หรือเพียงแค่วัตถุตามภาษาการเขียนโปรแกรมที่เราเลือกใช้

ช่องว่างและการเยื้องใช้ในไฟล์ YAML เพื่อแสดงถึงการซ้อน

หมายเหตุ: สามารถใช้ช่องว่างสำหรับการเยื้องในไฟล์ YAML เท่านั้น ไม่อนุญาตให้ใช้อักขระแท็บ ตราบใดที่การเยื้องทำอย่างสม่ำเสมอ ไม่สำคัญว่าจะใช้พื้นที่เท่าใด

ไวยากรณ์ YAML

รูปแบบ YAML ใช้โหนด 3 ประเภทเป็นหลัก:

  • แผนที่/พจนานุกรม: แผนที่ เนื้อหาของโหนดคือชุดที่ไม่เรียงลำดับของ คีย์/ค่า ปม คู่โดยมีข้อกำหนดว่าแต่ละคีย์ต้องแตกต่างกัน ไม่มีการกำหนดข้อจำกัดเพิ่มเติมบนโหนดโดย YAML
  • อาร์เรย์/รายการ: หนึ่ง แถว เนื้อหาของโหนดคือชุดของโหนดตั้งแต่ศูนย์ขึ้นไป ลำดับอาจรวมถึงโหนดเดียวกันมากกว่าหนึ่งครั้ง โดยเฉพาะอย่างยิ่ง มันอาจมีแม้กระทั่งตัวเอง
  • ตัวอักษร (สตริง ตัวเลข บูลีน ฯลฯ): ลำดับของศูนย์หรือมากกว่า อักขระ Unicode สามารถใช้เพื่อแสดงข้อมูลทึบแสงที่ประกอบเป็น เกลา เนื้อหาของโหนด

ในบทความนี้ เราจะมาดูการแปลงเนื้อหาอาร์เรย์ YAML เป็นรายการใน Java โดยเฉพาะ มีไลบรารีโอเพ่นซอร์สมากมาย แต่ที่นิยมมากที่สุดคือ แจ็คสัน และ งูYAML. ในคู่มือนี้ เราจะใช้ SnakeYaml เป็นห้องสมุดของเราเพื่อแยกวิเคราะห์เนื้อหา YAML

งูYaml

งูYAML เป็นแพ็คเกจการแยกวิเคราะห์ YAML ที่มี API ระดับสูงสำหรับการทำให้เป็นอนุกรมของเอกสาร YAML และการดีซีเรียลไลซ์เซชัน จุดเริ่มต้นสำหรับ SnakeYAML คือ Yaml ระดับ. สามารถโหลดเอกสารหรือไฟล์ YAML ได้โดยใช้ load() วิธีหรือในชุดงานผ่านทาง loadAll() กระบวนการ. เมธอดใช้ข้อมูล YAML ของแท้ในรูปแบบของออบเจกต์สตริงและ InputStreamsซึ่งเป็นประเภทไฟล์ทั่วไปที่ต้องพบเจอ

ให้ : โครงสร้างโดยกำเนิดของไฟล์ YAML SnakeYAML ทำงานได้ดีกับ แผนที่จาวาแต่เราอาจใช้ unique . ด้วย วัตถุ Java.

หากต้องการรวมห้องสมุดในโครงการของเรา ให้เพิ่มการพึ่งพาต่อไปนี้ในของคุณ 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

จากนั้นเราสามารถโหลดเนื้อหาไฟล์เป็น an 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

นี่ถือได้ว่าเป็น Java Map มี : โดยที่ค่าเป็น an แถว. ดังนั้นข้อมูลจะยังคงโหลดเป็น 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

สามารถแยกวิเคราะห์เป็น Java 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 class WebsiteContent ที่จะประกอบไปด้วย List ของทักษะและ a 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 class object เราต้องระบุประเภทข้อมูลที่เราต้องการจะส่งข้อมูลเข้าไป ดิ 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 ยังเสนอตัวเลือกการจัดรูปแบบ ดังนั้นคุณจึงสามารถปรับเปลี่ยนและปรับแต่งให้เหมาะกับความต้องการของเราได้

ประทับเวลา:

เพิ่มเติมจาก สแต็ค