繁体   English   中英

如何将 csv 转换为嵌套在 java 中的 Json?

[英]How to convert csv To nested Json in java?

我有以下格式的 csv 文件

A_aa,A_ab,A_ac,A_ad,B_BB_ba,B_BB_BBB_bb
1,2,3,4,5,6

我想将其转换为以下嵌套 json

{
   'A':{
        'aa' : '1',
        'ab' : '2',
        'ac' : '4',
        'ad' : '5',
    }
    'B':{
        'BB':{
            'ba' : '5',
            'BBB':{
                'bb' : '6'
            }
        }
    }
}

我给你写了部分解决方案。 请使用 maven 依赖

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.0</version>
</dependency>

java class:

package com.mycompany.app;
import com.google.gson.Gson;

public class Car 
{
    public A A;
    public B B;


    public A getA()
    {
        return A;
    }


    public void setA(A a)
    {
        this.A = a;
    }


    public B getB()
    {
        return B;
    }


    public void setB(B b)
    {
        this.B = b;
    }


    public class A {
        String aa;
        String ab;
        String ac;
        String ad;
        public String getAa()
        {
            return aa;
        }
        public void setAa(String aa)
        {
            this.aa = aa;
        }
        public String getAb()
        {
            return ab;
        }
        public void setAb(String ab)
        {
            this.ab = ab;
        }
        public String getAc()
        {
            return ac;
        }
        public void setAc(String ac)
        {
            this.ac = ac;
        }
        public String getAd()
        {
            return ad;
        }
        public void setAd(String ad)
        {
            this.ad = ad;
        }   

    }

    public class B {
        public BB BB;


        public BB getBb()
        {
            return BB;
        }


        public void setBb(BB bb)
        {
            this.BB = bb;
        }



        public class BB {
            String ba;
            public BBB BBB;

            public String getBa()
            {
                return ba;
            }

            public void setBa(String ba)
            {
                this.ba = ba;
            }

            public BBB getBbb()
            {
                return BBB;
            }

            public void setBbb(BBB bbb)
            {
                this.BBB = bbb;
            }

            public class BBB {
                public String bb;

                public String getBb()
                {
                    return bb;
                }

                public void setBb(String bb)
                {
                    this.bb = bb;
                }               

            }

        }

    }


    public static void main(String[] args) 
    {   
    String line1="A_aa,A_ab,A_ac,A_ad,B_BB_ba,B_BB_BBB_bb";
    String line2="1,2,3,4,5,6";

    String[] partsLinke1 = line1.split(",");
    String[] partsLinke2 = line2.split(",");
    Car c=new Car();
    Gson gson = new Gson();


    int k=0;

    for(int i=0; i<partsLinke1.length; i++) {
        System.out.println(partsLinke1[i]);
        String[] parts=partsLinke1[i].split("_");
        for(int j=0; j<parts.length; j++) {
            System.out.println(parts[j]);
            if(parts[j].equals("A")) {

                Car.A aJson=c.new A();

                if(parts[j+1].equals("aa")) {

                    aJson.setAa(partsLinke2[k]);
                    c.setA(aJson);
                }

            }


        }

    }
    String json = gson.toJson(c);
    System.out.println(json);

    }
}

和 output:

A_aa
A
aa
A_ab
A
ab
A_ac
A
ac
A_ad
A
ad
B_BB_ba
B
BB
ba
B_BB_BBB_bb
B
BB
BBB
bb
{"A":{"aa":"1"}}

我想现在你写 rest 会更容易;)

您的问题可以分为 2 个子问题。
Q1:如何将下划线('_')分隔的字符串模式转换为嵌套的 map。 Because once you can achieve this, you can convert the map to JSON string by using any one of the most popular Json libraries such as Jackson or Gson ,
Q2:如何解析 CSV 文件。 我想已经有很多文章讨论过这个问题。

对于第一个子问题,受@Andreas 在Generate Nested Map from Path String in Java中的回答启发,问题可以通过以下 ZC1C425268E68385D1AB5074C17A94F1 解决:

public static void generateNestedMap(Map<String, Object> map, String path, Object value) {
    int start = 0;
    for (int end; (end = path.indexOf('_', start)) != -1; start = end + 1)
        map = (Map<String, Object>) map.computeIfAbsent(path.substring(start, end), k -> new HashMap<String, Object>());
    map.put(path.substring(start), value);
}

然后您可以将给定的字符串和相应的值存储在 map 中, Map<String, Object> result如下:

代码片段

Map<String, Object> result = new HashMap<>();
generateNestedMap(result, "A_aa", 1);
generateNestedMap(result, "A_ab", 2);
generateNestedMap(result, "A_ac", 3);
generateNestedMap(result, "A_ad", 4);
generateNestedMap(result, "B_BB_ba", 5);
generateNestedMap(result, "B_BB_BBB_bb", 6);
System.out.println(result.toString());

控制台 output

{A={aa=1,ab=2,ac=3,ad=4},B={BB={BBB={bb=6},ba=5}}}

之后,您可以使用Jackson库轻松地将 map 转换为 JSON 字符串,如下所示:

ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(result);
System.out.println(jsonStr);

而它的 output 应该是:

{"A":{"aa":1,"ab":2,"ac":3,"ad":4},"B":{"BB":{"BBB":{"bb": 6},"ba":5}}}

对于第二个子问题,还有很多库,例如OpenCSVApache Commons CSV来处理这个问题,我不会详细介绍 go。

首先,拆分这两行以获得一个names和一个values数组:

    String line1 = "A_aa,A_ab,A_ac,A_ad,B_BB_ba,B_BB_BBB_bb";
    String line2 = "1,2,3,4,5,6";

    String[] names = line1.split(",");
    String[] values = line2.split(",");

创建Map的结构并将每个名称/值对添加到其中:

    Map<String,Object> root = new HashMap<>();
    for (int i = 0; i < names.length; ++i) {
        String name = names[i];
        String value = values[i];
        addValue(root, name.split("_"), value);
    }

方法addValue如下所示:

private static void addValue(Map<String,Object> map, String[] path,
        String value) {
    for (int i = 0; i < path.length-1; ++i) {
        String elem = path[i];
        Object current = map.get(elem);
        Map<String,Object> map2;
        if (current instanceof Map) {
            map2 = (Map<String,Object>)map.get(elem);
        } else {
            map2 = new HashMap<>();
            map.put(elem, map2);
        }
        map = map2;
    }
    map.put(path[path.length-1], value);
}

最后,将结构体转换为 JSON。 这里使用了库 Gson:

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    gson.toJson(root, System.out);

CSV文件第一行是字段头(下划线表示层级关系,详细数据从第二行开始,你需要将CSV转换为JSON,难点在于动态解析,因为涉及到分组,递归,循环,条件判断,字符串拼接,如果用Java来实现,代码会很长。

使用SPL很容易实现这个,开源的Java package。五行代码就够了:

一种
1个 =file("json.csv").import@cw()
2个 =i=0,A1(1).(~.split("_")).(~|A1(2)(#)).(~.run(~="\""/~/"\" “))
3个 函数递归(AA) >B1=left(B1,-i)/"{}"/right(B1,i),i+=1,AA.group(~(1)).(if(~.len()==1 && ~ (1).len()==2,B1=left(B1,-i)/~(1).concat(":")/right(B1,i),(B1=left(B1,-i) /~(1)(1)/":"/right(B1,i),func(递归,~.(~.m(2:))))))
4个 =函数(递归,A2)
5个 =替换(替换(B1,"\"\"","\",\""),"}\"","},\"")

SPL 提供 JDBC 驱动,由 Java 调用。只需将上述 SPL 脚本存储为 recurse.splx,并在调用存储过程时在 Java 中调用它:

…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call recurse()");
st.execute();
…

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM