2016-10-09 4 views
0

다음과 같이 JSON 스키마를 읽음으로써 svg에 다음 구조를 그리는 재귀 JavaScript 함수를 구현했습니다.요소에서 JSON 경로를 얻는 방법

선택한 노드의 JSON 경로를 확인하는 방법이 있습니까? 마찬가지로 사용자가 노드 (예 : country:string)를 클릭하면 JSON 경로 (person.address.country)를 반환 할 수 있습니까?

업데이트 : 나는 백본 모델을 사용하고 있으므로 나중에 사용하기 위해 노드의 속성으로 추적하고 JSON 경로를 추가하는 것이 좋습니다. 나는 다른 직접적인 방법을 찾고있다.

//initiate 
    var title = data.title || "Root"; 
    var count = this.traverseJSONSchema(data, title, 0, 0, this.get('tempParent')); 

//function 
traverseJSONSchema: function (root, rootName, level, rank, resultPane) { 
        var height = this.nodeHeight, 
          width = this.containerWidth, 
          margin = width/6, 
          x = 0, 
          overhead = rank * margin, 
          y = level * height; 
        var tempParent = resultPane.append("g").attr("class", "nested-group"); 
        if (root.type === "object") { 
         if (rootName !== "") { 
          var nodeText = rootName + ":" + root.type; 
          var node = new DataMapper.Models.Node({parent: tempParent, text: nodeText, x: x, y: y, type: this.get('type'), category: "object", height: height, width: width}); 
          node.drawContainerNode(overhead); 
          rank++; 
          level++; 
         } 
         var nestedParent = tempParent.append("g").attr("class", "nested-group"); 
         var keys = root.properties; //select PROPERTIES 
         for (var i = 0; i < Object.keys(keys).length; i++) { //traverse through each PROPERTY of the object 
          var keyName = Object.keys(keys)[i]; 
          var key = keys[keyName]; 
          level = this.traverseJSONSchema(key, keyName, level, rank, tempParent); 
         } 

        } else if (root.type === "array") { 
         var keys = root.items; //select ITEMS 
         if (rootName !== "") { 
          var nodeText = rootName + ":" + root.type + "[" + keys.type + "]"; 
          var node = new DataMapper.Models.Node({parent: tempParent, text: nodeText, x: x, y: y, type: this.get('type'), category: "array", height: height, width: width}); 
          node.drawContainerNode(overhead); 
          rank++; 
          level++; 
         } 

         level = this.traverseJSONSchema(keys, "", level, rank, tempParent); //recurse through the items of array 
        } else if (["string", "integer", "number", "boolean"].indexOf(root.type) > -1) { //when the type is a primitive 
         tempParent.classed("nested-group", false); 
         if (rootName !== "") { 
          var nodeText = rootName + ":" + root.type; 
          var node = new DataMapper.Models.Node({parent: tempParent, text: nodeText, x: x, y: y, type: this.get('type'), category: root.type, height: height, width: width}); 
          node.drawContainerNode(overhead); 
          rank++; 
          level++; 
         } 
        } 
        return level; 
       } 
+2

네 것이 가능하다. 더 나은 이해를 위해 텍스트 형식으로 개체를 포함 할 수 있습니다. 제발 여기 좀 봐 : [mcve] –

+0

그냥 힌트, [JSON] (http://json.org/) 항상 문자열입니다. –

+0

@NinaScholz 조언을 주셔서 감사합니다. 나는 스키마를 속성으로 읽는 동안 추적을 유지하고 JSON 경로를 추가 할 것을 고려하고있었습니다. 직접적인 방법이 있습니까? – SachiDangalla

답변

2

당신은 concatination에 대한 특별 대우 경로를 사용할 수 있습니다 다음과 같이

enter image description here

재귀 코드 (백본 기능)

{ 
    "title": "person", 
    "type": "object", 
    "properties": { 
    "first name": { "type": "string" }, 
    "last name": { "type": "string" }, 
    "age":{ "type":"number"}, 
    "birthday": { "type": "string", "format": "date-time" }, 
    "address": { 
     "type": "object", 
     "properties": { 
     "street address": { 
     "type": "object", 
     "properties": { 
     "house number": { "type": "number" }, 
     "lane": { "type": "string" } 
     }  
    }, 
     "city": { "type": "string" }, 
     "state": { "type": "string" }, 
     "country": { "type" : "string" } 
     }  
    }, 
    "phone number": { 
     "type": "array", 
     "items": { 
     "type": "object", 
     "properties": { 
      "location": { 
      "type": "string" 
      }, 
      "code": { 
      "type": "number" 
      } 
     }, 
     "required": [ 
      "location", 
      "code" 
     ] 
     } 
    }, 
    "children": { 
     "type": "array", 
     "items": { 
     "type": "string" 
     } 
    }, 
    "nickname":{"type":"string"} 
    } 
} 

이다.

function getPath(object, search) { 
 
    function iter(o, p) { 
 
     return Object.keys(o).some(function (k) { 
 
      if (k === key && o[k] && o[k].type === value) { 
 
       path = p.concat(k).join('.'); 
 
       return true; 
 
      } 
 
      if (o[k] !== null && typeof o[k] === 'object') { 
 
       return iter(o[k], 
 
        k === 'properties' && !o.title ? 
 
         p : 
 
         p.concat(k === 'properties' && o.title ? o.title : k) 
 
       ); 
 
      } 
 
     }); 
 
    } 
 

 
    var parts = search.split(':'), 
 
     key = parts[0], 
 
     value = parts[1], 
 
     path; 
 

 
    iter(object, []); 
 
    return path; 
 
} 
 

 
var data = { title: "person", type: "object", properties: { "first name": { type: "string" }, "last name": { type: "string" }, age: { type: "number" }, birthday: { type: "string", format: "date-time" }, address: { type: "object", properties: { "street address": { type: "object", properties: { "house number": { type: "number" }, lane: { type: "string" } } }, city: { type: "string" }, state: { type: "string" }, country: { type: "string" } } }, "phone number": { type: "array", items: { type: "object", properties: { location: { type: "string" }, code: { type: "number" } }, required: ["location", "code"] } }, children: { type: "array", items: { type: "string" } }, nickname: { type: "string" } } }; 
 

 
console.log(getPath(data, 'country:string'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

관련 문제