1

私のJSONシリアル化されたデータには、ネストされたオブジェクトがあります:

{
  "A" : { "A1": 1,
          "A2": 2 },
  "B" : { "B1": 3,
          "B2": 4 }
}

私が影響を与えることができない特定の制約のために、構造を平坦化する必要があります。これは、深度が 1 より大きいすべてのオブジェクトを文字列としてエンコードする必要があることを意味します。上記の例に適用すると、次のようになります。

{
  "A" : "\{\"A1\": 1, \"A2\": 2\}"
  "B" : "\{\"B1\": 3, \"B2\": 4\}"  
}

JSON Schemaでこの制約を表現する必要があるため、構文規則にかなり縛られています。stringこれらのオブジェクトのタイプは、またはのいずれかになると思いますobject

{
  "title": "My Schema",
  "type": "object",
  "properties": {

    "A": {
      "type": "string vs. object" 
    "B": {
      "type": "string vs. object"
}
4

2 に答える 2

5

同意します。選択するobjectstring入力します。JSON スキーマのドキュメントを調べましたが、必要なほど明確に制約を表現するものは見つかりませんでした。したがって、そこにある 2 つのアプローチについての短い議論が頭に浮かびます。

タイプ文字列

JSON スキーマでは、オブジェクトを含む 7 つのプリミティブ型が定義されています。文字列は単純に JSON 文字列として定義されます。RFC 4627 では、JSON 文字列を次のように定義しています。

文字列は 0 個以上の Unicode 文字のシーケンスです

文字列の内容を制限する必要がありますが、これはあなたのケースに当てはまります。問題は、制限をどのように伝えるかです。a を使用しdescriptionて別のサブスキーマを参照します。文字列に を定義し patternて、サブスキーマを正規表現としてエンコードすることもできます。ただし、これは非常にエラーが発生しやすく、人間が読めるものではありません。ただし、データのスキーマ検証を改善するために使用できます。

{
  "title": "My Schema",
  "type": "object",
  "properties": {

    "A": {
      "type": "string".
      "description": "Please refer to http://... for the subschema."
    },
    "B": {
      "type": "string"
      "description": "Please refer to http://... for the subschema."
    }
}

これには利点があり、JSON プロバイダーがそのプロパティに文字列を配置する必要があることは間違いなく明らかです。欠点は、完全なスキーマを一度に見ることができず、説明が見落とされる可能性があり、ルックアップ プロセスも煩雑になることです。最後に、タイプを見ると非常に混乱しますstringが、 aobjectはサブスキーマで定義されています。

型オブジェクト

型をそのまま使用するだけで、文字列を使用することのすべての欠点を回避できます。ここでの問題は、文字列エンコーディングでなければならないという説明が見落とされることです。

{
  "title": "My Schema",
  "type": "object",
  "properties": {

    "A": {
      "description": "Must be encoded as string",
      "type": "object",
      "properties": { "A1": { "type": "string" }, "A2": { "type": "string" } }
    },
    "B": {
      "description": "Must be encoded as string",
      "type": "object"
      "properties": { "A1": { "type": "string" }, "A2": { "type": "string" } }
    }
}

stringタイプを使用して定義するなど、いつでも完全に偽物を作成できますがproperties、これは無効な JSON スキーマになります。


Type Objectアプローチを使用することをお勧めします。この制約がありますが、文字列型を使用すると、その背後にあるデータが常に劣化します。制約は、他の方法で強制することができます。誰がデータを提供するかを監視し、すべての関係者に制約を伝え、この制約に関して有効でないデータをブロックします。

そして、おそらくこの制約は永久に存在しない可能性があり、それが変更された場合は、スキーマを再度変更する必要があり、それ以外の場合は、文字列エンコーディングの要件を示すコメントを削除するだけで済みます.

于 2013-08-19T12:09:12.587 に答える
1

すでに回答を選択されていることは承知していますが、ここでは原則について触れておきたいと思います。

JSON スキーマは、「セマンティック」検証を回避しようとします。つまり、スカラー型内のデータの検証 (文字列形式や数値精度の強制など) を意味します。

このような文字列値の内部形式を文書化したい場合は、"format"値 (標準には適切な値がないため、おそらくカスタム値) を使用できます。

...または使用できます"media"。このスキーマ キーワードの値は、"type"文字列値のメディア タイプを指定するプロパティを持つことができるオブジェクトです。したがって、プロパティは次のようになります。

{
    "type": "string",
    "media": {
        "type": "application/json"
    }
}

バリデーターは を無視することが許可されて"format"おり、使用して検証する可能性はほとんどあり"media"ません (接線的には言及されていません) が、フラット化されたデータ形式を記述"media"するという点では、最も正確な方法です。

(ただし、受け入れられた回答が述べているように、これをデータ制約ではなく奇妙なシリアル化方法として扱うことは、多くの点でより洗練されたソリューションです)。

于 2013-09-10T15:49:05.670 に答える