簡體   English   中英

如何解析郵遞員收藏?

[英]how to parse postman-collection?

目標

我正在嘗試解析 postman_echo 集合 json 並將結果保存到磁盤上的新 json 副本中,從而產生與原始文件相同的文件。

我更喜歡該語言的內置數據結構,但使用 json 庫也應該不錯。 不確定 Antlr4 是更好的方法。

后續問題
是否可以在發布請求的正文中允許任何有效的嵌套 json?

更新: https://github.com/chakpongchung/postman-parser最后我們想出了這個令人滿意的解決方案。

如果結構不太動態(使用 Play JSON),則 zoran 提到的替代方法是創建一個案例 class。 這將更容易比較結果。

case class MyObject(
  queryString: List[KeyValue],
  method: String,
  url: String,
  httpVersion: String
) ... and so on

object MyObject {
    implicit val format: Format[MyObject] = Json.format
}

case class KeyValue(name: String, value: String)

object KeyValue {
    implicit val format: Format[KeyValue] = Json.format
}

然后,您只需要執行以下操作:

object JsonParser extends App {
  val postman_collections = "./scala_input.json"
  val jsonifiedString = scala.io.Source.fromFile(postman_collections).mkString

  val myJsonData = Try(Json.parse(jsonifiedString)).map(_.as[MyObject])

  myJsonData match {
    case Success(myValue) => // compare your case class here
    case Failure(err) => println("none")
  }
}

您的解析器存在多個問題,其中大多數是您嘗試使用默認解析器將 Json object 作為字符串處理。 例如,在 Request 中,您將 header 作為 Seq[String] 處理,而它實際上是(鍵,值)對的 Seq。 對於這種特殊情況,您應該將其更改為以下內容:

case class Request(
                method: String,
                header: Seq[HeaderItem], // header: []
                url: Option[Url] = None,
                description: String = ""
              )
object Request {
   implicit val format: Format[Request] = Json.using[Json.WithDefaultValues].format

case class HeaderItem(key: String, value: String)

object HeaderItem {
   implicit val format: Format[HeaderItem] = Json.format
 }

如果需要,您可以將 header 轉換為 Seq[String] ,但您必須為此編寫自定義讀取。 在上述情況下,您也有缺少描述的情況,因此您希望使用默認值來處理。 您在其他幾個地方也有這樣的問題需要處理,例如“響應”。

我注意到的另一個問題是如何處理 Json 字符串中的“類型”屬性。 類型是保留關鍵字,可以用`包裹來處理,例如

case class Script(
    `type`: String,
     exec: Seq[String]
)

我不確定我是否很好地理解了您的問題,但是如果您嘗試遍歷 json 字符串,您可以嘗試這樣的操作:

  import play.api.libs.json.{JsObject, JsValue, Json}
  import scala.util.{Failure, Success, Try}


  object JsonParser extends App {
    val postman_coolections = "./resources/scala_input.json"
    val jsonifiedString = scala.io.Source.fromFile(postman_coolections).mkString

    val json: JsValue = Try(Json.parse(jsonifiedString)) match {
      case Success(js) => js
      case Failure(ex) => throw new Exception("Couldn't parse json", ex)
   }
 json.asInstanceOf[JsObject].fields.foreach{
   case (key: String, value: JsValue)=>
      println(s"Key:$key value:${value.toString}")
      writeFile(s"$key.json", Json.prettyPrint(value))
 }

//writing the whole postman input as a single file

writeFile("postmanInputFormatted.json", Json.prettyPrint(json))
writeFile("postmanInput.json", Json.stringify(json))

// To access individual property one option is to use this approach

val lookedValue = json \ "postData" \ "params" \ 1 \ "hello" \ "test"

lookedValue match {
  case JsDefined(value) => println(s"Test value is $value")
  case JsUndefined() => println("Didn't find test value")
}
// or
val lookedValueAlt = (json \ "postData" \ "params" \ 1 \ "hello" \ "test").getOrElse(throw SomeException)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM