使用 lift-json 解析文档片段

发布于 2024-12-15 21:46:00 字数 2452 浏览 1 评论 0原文

当我可能不知道我正在解析的文档的确切结构和顺序时,我尝试使用 lift-json 解析 JSON 文档。该文档包含“对象”列表,所有对象都组织成该对象类型的部分,每个部分都以该类型命名。我尝试过各种方法来循环类型,对类型名称进行模式匹配,然后尝试获取对象列表,但它似乎永远无法正常工作。我要么得到一个空白列表,要么得到一个关于无法找到正确的 JSON 块来映射到我的案例类的错误。

这里有一些(几乎是伪的)代码,与我所得到的一样接近:

case class TypesQueries(queries: Map[String, JValue]);

case class AddressQueries(addresses: List[AddressQuery]);
case class AddressQuery(street: String, city: String, state: String, zip: Int)

case class NameQueries(names: List[NameQuery]);
case class NameQuery(firstName: String, lastName: String);

case class EmailQueries(emails: List[EmailQuery]);
case class EmailQuery(emailAddress: String);

val jsonData = parse("""{
    "queries" : {
        "addresses" : [
            {
                "street" : "1234 Main St.",
                "city" : "New York",
                "state" : "New York",
                "zip" : 12345
            },
            {
                "street" : "9876 Broadway Blvd.",
                "city" : "Chicago",
                "state" : "IL",
                "zip" : 23456
            }
        ],
        "names": [
            {
                "firstName" : "John",
                "lastName" : "Doe"
            }
        ],
        "emails" : [
            {
                "emailAddress" : "[email protected]"
            },
            {
                "emailAddress" : "[email protected]"
            }
        ]
    }
}""");


val typesQuery = parse(jsonData).extract[TypesQueries];

typesQuery.queries.foreach { case(queryType, queryDefinition) =>
    queryType match {
        case "addresses" =>
            // These extract methods do not work.
            val addressQueries = queryDefinition.extract[AddressQueries];
        case "names" =>
            // These extract methods do not work.
            val nameQueries = queryDefinition.extract[NameQueries];
        case "emails" =>
            // These extract methods do not work.
            val emailQueries = queryDefinition.extract[EmailQueries];
    }
}

“地址”、“名称”和“电子邮件”可以按任何顺序出现在“查询”中,并且它们的数量可能是可变的。

最后,我希望能够提取相应类型列表的对象列表,然后在解析完成后,将各种对象列表传递给适当的方法。

所以,问题是:如果我事先不知道完整的文档结构是什么,如何解析为 lift-json 中的案例类。

I'm trying to parse a JSON document with lift-json when I may not know the exact structure and order of the document that I'm parsing. The document contains list of "objects", all organized into sections for that object type with each section named for that type. I've played around with various ways to loop over the types, pattern-matching on the type name and then trying to get that list of objects out but it never seems to work properly. I either get a blank list or an error about not being able to find the proper JSON chunk to map to my case classes.

Here's some (almost pseudo) code that is as close as I've come:

case class TypesQueries(queries: Map[String, JValue]);

case class AddressQueries(addresses: List[AddressQuery]);
case class AddressQuery(street: String, city: String, state: String, zip: Int)

case class NameQueries(names: List[NameQuery]);
case class NameQuery(firstName: String, lastName: String);

case class EmailQueries(emails: List[EmailQuery]);
case class EmailQuery(emailAddress: String);

val jsonData = parse("""{
    "queries" : {
        "addresses" : [
            {
                "street" : "1234 Main St.",
                "city" : "New York",
                "state" : "New York",
                "zip" : 12345
            },
            {
                "street" : "9876 Broadway Blvd.",
                "city" : "Chicago",
                "state" : "IL",
                "zip" : 23456
            }
        ],
        "names": [
            {
                "firstName" : "John",
                "lastName" : "Doe"
            }
        ],
        "emails" : [
            {
                "emailAddress" : "[email protected]"
            },
            {
                "emailAddress" : "[email protected]"
            }
        ]
    }
}""");


val typesQuery = parse(jsonData).extract[TypesQueries];

typesQuery.queries.foreach { case(queryType, queryDefinition) =>
    queryType match {
        case "addresses" =>
            // These extract methods do not work.
            val addressQueries = queryDefinition.extract[AddressQueries];
        case "names" =>
            // These extract methods do not work.
            val nameQueries = queryDefinition.extract[NameQueries];
        case "emails" =>
            // These extract methods do not work.
            val emailQueries = queryDefinition.extract[EmailQueries];
    }
}

"addresses", "names" and "email" may come in any order inside "queries" and there may be a variable number of them.

In the end, I want to be able to extract lists of objects for the respective list of types and then, once the parsing is complete, pass the various lists of objects to the appropriate method.

So, the question is: How can I parse into case classes in lift-json if I do not know what the complete document structure will be ahead of time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧伤慢歌 2024-12-22 21:46:00

你非常接近,这适用于 repl:(

更新

typesQuery.queries.foreach { 
  case(queryType, queryDefinition) => queryType match {
    case "addresses" => val addressQueries = typesQuery.queries.extract[AddressQueries]; println(addressQueries)
    case "names" => val nameQueries = typesQuery.queries.extract[NameQueries]; println(nameQueries)
    case "emails" => val emailQueries = typesQuery.queries.extract[EmailQueries]; println(emailQueries)
  }
}

这个想法是 foreach“删除”包含每个“对象”的列表,因此我们调用 typesQuery.queries.extract 来帮助案例类与我们解析的 json 匹配

You were very close, this works on the repl:

(Updated)

typesQuery.queries.foreach { 
  case(queryType, queryDefinition) => queryType match {
    case "addresses" => val addressQueries = typesQuery.queries.extract[AddressQueries]; println(addressQueries)
    case "names" => val nameQueries = typesQuery.queries.extract[NameQueries]; println(nameQueries)
    case "emails" => val emailQueries = typesQuery.queries.extract[EmailQueries]; println(emailQueries)
  }
}

The idea is that the foreach "removes" the list that encloses each "object", so we call typesQuery.queries.extract to help the case classes match our parsed json

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文