JSON과 동등한 XSLT [닫기]


411

JSON과 동등한 XSLT 가 있습니까? XSLT가 XML을 처리하는 것처럼 JSON에서 변환을 수행 할 수있는 기능이 있습니다.


1
Btw, 어떤 언어 / 플랫폼이 있습니까?
StaxMan

6
@StaxMan XSLT는 많은 언어와 플랫폼에서 실제로 구현되는 표준이며, 제 질문은 비슷한 노력을 목표로합니다.
luvieere

36
질문에 +1 많은 사람들이 XSLT를 간과하거나 싫어하는 것처럼 보이지만 단순히 XML의 자세한 내용에 대한 반응 일 수 있습니다. 실제로 XML이 점차 유리 해지지 않기 때문에 XSLT를 사용할 기회가 점점 줄어들고 있습니다. JSON과 동등한 XSLT는 훌륭합니다.
Nicolas Le Thierry d' Ennequin

10
@ NicolasLeThierryd'Ennequin 합의. 많은 사람들이 XML을 싫어하므로 XSLT를 무시합니다. 도구의 XML 에코 시스템은 Java 개발자에게도 무겁기 때문에 더 많은 사람들이 떠나게됩니다. 그러나 2000 년대 중반에 XSLT에 푹 빠져서 XML 생태계 외부에 직접적인 영향을 미치지 않는 엄청난 힘이 있습니다. 나는 JSON과 동등한 것을 좋아할 것입니다 !
Zearin

답변:


77

재미있는 생각. Google에서 일부 검색을 수행하면 다음과 같은 몇 가지 관심있는 페이지가 생성되었습니다.

도움이 되었기를 바랍니다.


10
응, 고마워 그게 내가 찾던거야 이 기술이 인기가 많지 않은 것은 유감입니다 .JSON은 REST 스타일 서비스에서 반환 형식으로 자주 사용되며 변환을 구현하는 표준 방법을 사용하는 것이 좋습니다.
luvieere

8
이 코드는 사용 string.eval () ... :-(
dreftymac

링크 전용 답변
Jean-François Fabre

102

JSON 용 XSLT 동등 항목-후보 목록 (도구 및 사양)

도구

  1. XSLT

    fn : json-to-xml 의 목표로 JSONXSLT를 사용할 수 있습니다 . .

    이 섹션에서는 XSLT를 사용하여 JSON 데이터를 처리 할 수있는 기능에 대해 설명합니다.

  2. jq

    jq는 JSON 데이터에 대한 sed와 같습니다.이를 사용하여 sed, awk, grep 및 friends가 텍스트로 재생할 수있는 것과 동일한 방식으로 구조화 된 데이터를 슬라이스 및 필터링하고 매핑하고 변환 할 수 있습니다. 다른 OS에 대한 설치 패키지가 있습니다.

  3. jj

    JJ는 JSON 문서에서 값을 검색하거나 업데이트하는 빠르고 간단한 방법을 제공하는 명령 줄 유틸리티입니다. GJSON과 SJSON이 제공합니다.

  4. fx

    명령 줄 JSON 처리 도구

    • 새로운 구문을 배울 필요가 없습니다
    • 일반 자바 스크립트
    • 서식 및 강조
    • 독립 바이너리
  5. jl

    jl ( "JSON lambda")은 JSON 쿼리 및 조작을위한 작은 기능 언어입니다.

  6. 심한 상하의 움직임

    변환의 "사양"이 JSON 문서 인 Java로 작성된 JSON에서 JSON으로의 변환 라이브러리

  7. 그론

    JSON을 그렙 가능하게 만드십시오! gron은 JSON을 개별 할당으로 변환하여 원하는 것을 쉽게 잡을 수 있고 절대 '경로'를 볼 수 있습니다. 대량의 JSON을 반환하지만 끔찍한 문서를 가진 API를 쉽게 탐색 할 수 있습니다.

  8. json

    json은 JSON 작업을위한 빠른 CLI 도구입니다. 외부 파일이없는 단일 파일 node.js 스크립트입니다 (node.js 자체 제외).

  9. json-e

    JSON-e는 JSON 객체에 컨텍스트를 포함하기위한 데이터 구조 매개 변수화 시스템입니다. 중심 아이디어는 데이터 구조를 "템플릿"으로 취급하고 다른 데이터 구조를 컨텍스트로 사용하여 변환하여 출력 데이터 구조를 생성하는 것입니다.

  10. JSLT

    JSLT는 JSON을위한 완전한 쿼리 및 변환 언어입니다. 언어 디자인은 jq, XPath 및 XQuery에서 영감을 얻었습니다.

  11. JSONata

    JSONata는 JSON 데이터를위한 간단한 쿼리 및 변환 언어입니다. XPath 3.1의 '위치 경로'시맨틱에서 영감을 받아 정교한 쿼리를 작고 직관적 인 표기법으로 표현할 수 있습니다.

  12. json-transforms Last Commit 2017 년 12 월 1 일

    JSON 데이터 변환에 대한 재귀 패턴 일치 방식을 제공합니다. 변환은 JSON 객체의 구조와 일치하는 규칙 세트로 정의됩니다. 일치하는 경우 규칙은 변환 된 데이터를 내 보내며 선택적으로 하위 개체를 변환하기 위해 반복됩니다.

  13. jsawk Last commit 2015 년 3 월 4 일

    Jsawk는 awk와 비슷하지만 JSON입니다. stdin에서 읽은 JSON 객체 배열로 작업하고 JavaScript를 사용하여 필터링하여 stdout에 인쇄되는 결과 배열을 생성합니다.

  14. 예이 Last Commit 2017 년 3 월 13 일

    테스트는 문서로 사용할 수 있습니다 https://github.com/pasaran/yate/tree/master/tests

  15. jsonpath-object-transform 마지막 커밋 2017 년 1 월 18 일

    JSONPath를 사용하여 객체 리터럴에서 데이터를 가져 와서 템플릿을 기반으로 새 객체를 생성합니다.

  16. 스테이플 마지막 커밋 2013 년 9 월 16 일

    스테이플 링은 JSON 객체의 XSLT 형식을 활성화하는 JavaScript 라이브러리입니다. Stapling은 JavaScript 템플릿 엔진 및 텍스트 / html 템플릿을 사용하는 대신 Ajax와 함께 비동기식으로로드 된 다음 클라이언트 측에 캐시 된 XSLT 템플릿을 사용하여 JSON 데이터 소스를 구문 분석 할 수있는 기회를 제공합니다.

명세서:

  • JsonPointer

    JSON 포인터는 JSON (JavaScript Object Notation) 문서에서 특정 값을 식별하기위한 문자열 구문을 정의합니다.

  • JsonPath

    JSONPath 표현식은 XPath 표현식이 XML 문서와 함께 사용되는 것과 동일한 방식으로 항상 JSON 구조를 참조합니다.

  • JSPath

    JSON 용 JSPath는 XPath for XML과 같습니다. "

  • JSONiq

    JSONiq의 주요 영감 원천은 XQuery이며, 이는 지금까지 반 구조화 된 데이터를위한 성공적이고 생산적인 쿼리 언어로 입증되었습니다


2
매우 상세하고 유용한 게시물에 감사드립니다. 한 줄짜리 JSON을 읽을 수있는 형태로 변환하려면 jq (목록의 2 번)가 최선의 선택입니다. 다시 감사합니다!
primehunter

1
나는 예쁜 인쇄를 위해 종종 json_pp 를 사용 합니다. 많은 배포판에서 사용할 수 있습니다.
jschnasse

70

JOLT 시도하십시오 . Java로 작성된 JSON에서 JSON으로의 변환 라이브러리입니다.

"JSON-> XML-> XSLT-> XML-> JSON"게임을하지 않기 위해 특별히 만들어졌으며, 복잡한 변환을위한 템플릿을 사용할 수는 없습니다.


4
+9000 : 이것은 심각한 프로젝트입니다! 후자. 예제가 포함 된 온라인 데모는 학습 곡선을 높이는
kevinarpe

15

jq-가볍고 유연한 명령 줄 JSON 프로세서

XSLT와 같은 템플릿 기반은 아니지만 더 간결합니다. 예를 들어, 추출 nameaddress필드를 배열로 :[.name, .address]

튜토리얼 은 Twitter의 JSON API를 변환하는 예제를 안내합니다. 매뉴얼 에는 많은 예제가 있습니다.


4
훨씬 적을 수 있기 때문에 더 간결합니다.
Ihe Onwuka

Json 트리에서 주어진 속성을 재귀 적으로 검색하는 방법을 찾지 못했습니다
Daniel

@Daniel 님 .. | .attr_name?이 찾고 계신가요? ( stedolan.github.io/jq/manual/#RecursiveDescent : ..에서 )
ankostis


15

XSLT는 http://www.w3.org/TR/xslt-30/#json에 표시된대로 JSON을 지원합니다 .

XML은 구분 기호 토큰에 꺾쇠 괄호를 사용하고 JSON은 괄호, 대괄호 등을 사용합니다. XML의 토큰 인식 비교가 적다는 것은 선언적 변환에 최적화 된 반면 스위치 문과 같은 더 많은 비교는 속도 때문에 스크립팅 언어의 명령형 코드가 유용한 추론 적 분기 예측을 가정합니다. 결과적으로 서로 다른 반 구조적 데이터 조합에 대해 반응 형 페이지의 일부로 XSLT 및 자바 스크립트 엔진의 성능을 벤치마킹 할 수 있습니다. 무시할 수있는 데이터 페이로드의 경우 XML 직렬화없이 JSON에서도 변환이 제대로 작동 할 수 있습니다. W3의 결정은 더 나은 분석을 기반으로해야합니다.


15

최근에 JSON 스타일 지정을 위해 좋아하는 도구 인 https://github.com/twigkit/tempo 를 찾았습니다 . XPATH 쿼리가 없어도 XSLT보다 훨씬 사용하기 쉬운 도구입니다.


9
변환의 최종 결과가 HTML이면 템포가 멋지게 보입니다. 그러나 암시 적 구조를 다른 구조로 재 배열하려는 경우 최종 결과는 여전히 JSON입니다. 여전히 XPath의 아날로그를 원하므로 변환을 기능적인 방식으로 작성할 수 있습니다.
Toddius Zho

1
템포는 정말 흥미 롭습니다. 그러나 xml을 브라우저 및 xslt (<? xsl-stylesheet>)로 보낼 수 있으며 브라우저는 xslt를 xml에 적용하여 추가 코드없이 xml의 정의 된보기를 표시합니다. 이것은 jsonT / tempo의 경우에도 마찬가지입니다.
Martin Meeser


11

도구가 부족하다고 말하면 필요가 없다는 것은 단지 질문을 구하는 것입니다. Linux에서 X 또는 Y를 지원할 때도 마찬가지입니다 (왜 그런 소수의 OS를위한 양질의 드라이버 및 / 또는 게임을 개발해야 하는가? 왜 대기업 및 하드웨어 회사가 개발하지 않은 OS에주의를 기울여야합니까?). 아마도 XSLT와 JSON을 사용해야하는 사람들은 JSON을 XML로 변환하는 다소 간단한 해결 방법을 사용하게됩니다. 그러나 이것이 최적의 해결책은 아닙니다. 그렇지 않습니까?

기본 JSON 형식이 있고 브라우저에서 "wysywyg"를 편집하려는 경우 XSLT가 문제에 대한 적절한 해결책 이상이 될 것입니다. 전통적인 자바 스크립트 프로그래밍으로 그것을하는 것은 arse에 고통이 될 수 있습니다.

실제로 템플릿 호출, 하위 프로세스 처리 등 자바 스크립트에 대한 일부 기본 명령을 해석하기 위해 하위 문자열 구문 분석을 사용하여 XSLT에 대한 "스톤 에이지"접근 방식을 구현했습니다. 확실히 JSON 객체로 변환 엔진을 구현하는 것이 훨씬 쉽습니다. XSLT를 구문 분석하기위한 본격적인 XML 파서를 구현합니다. 문제는 XML 템플릿을 사용하여 JSON 객체를 변환하려면 템플릿의 XML을 구문 분석해야한다는 것입니다.

XML (또는 HTML 또는 텍스트 등)로 JSON 객체를 변환하려면 구문과 변환 명령을 식별하는 데 사용해야하는 특수 문자를 신중하게 고려해야합니다. 그렇지 않으면 사용자 정의 템플릿 언어에 대한 파서를 디자인해야 할 것입니다. 그 길을 걸었을 때, 나는 그것이 예쁘지 않다고 말할 수 있습니다.

업데이트 (2010 년 11 월 12 일) : 2 주 동안 내 파서 작업을 수행 한 후이를 최적화 할 수있었습니다. 템플릿은 미리 구문 분석되고 명령은 JSON 객체로 저장됩니다. 변환 규칙도 JSON 객체 인 반면 템플릿 코드는 셸 코드와 유사한 HTML과 홈 브루어 구문이 혼합되어 있습니다. 복잡한 JSON 문서를 HTML로 변환하여 문서 편집기를 만들 수있었습니다. 코드는 편집기의 약 1K 줄 (개인 프로젝트이므로 공유 할 수 없음)과 JSON 변환 코드 (반복 명령, 간단한 비교, 템플릿 호출, 변수 저장 및 평가 포함) 약 990 줄입니다. MIT 라이센스에 따라 배포 할 계획입니다. 당신이 참여하고 싶다면 나에게 메일을 드롭.


11

나는 이것에 대해 내 자신의 작은 도서관을 최근에 썼다.

5.1 처리 모델 (XSLT REC) https://www.w3.org/TR/xslt#section-Processing-Model

JavaScript 코드의 몇 줄로 (가능한 한) 가능합니다.

다음은 완전하지 않은 몇 가지 사용 예입니다.

1. JSON에서 마크 업으로 :

깡깡이: https://jsfiddle.net/YSharpLanguage/kj9pk8oz/10

( D.1 문서 예 (XSLT REC)에서 영감을 얻음 ) https://www.w3.org/TR/xslt#section-Document-Example )

이 곳 :

var D1document = {
    type: "document", title: [ "Document Title" ],
    "": [
      { type: "chapter", title: [ "Chapter Title" ],
        "": [
        { type: "section", title: [ "Section Title" ],
          "": [
            { type: "para", "": [ "This is a test." ] },
            { type: "note", "": [ "This is a note." ] }
        ] },
        { type: "section", title: [ "Another Section Title" ],
          "": [
            { type: "para", "": [ "This is ", { emph: "another" }, " test." ] },
            { type: "note", "": [ "This is another note." ] }
        ] }
      ] }
    ] };

var D1toHTML = { $: [
  [ [ function(node) { return node.type === "document"; } ],
    function(root) {
      return "<html>\r\n\
  <head>\r\n\
    <title>\r\n\
      {title}\r\n".of(root) + "\
    </title>\r\n\
  </head>\r\n\
  <body>\r\n\
{*}".of(root[""].through(this)) + "\
  </body>\r\n\
</html>";
    }
  ],
  [ [ function(node) { return node.type === "chapter"; } ],
    function(chapter) {
      return "    <h2>{title}</h2>\r\n".of(chapter) + "{*}".of(chapter[""].through(this));
    }
  ],
  [ [ function(node) { return node.type === "section"; } ],
    function(section) {
      return "    <h3>{title}</h3>\r\n".of(section) + "{*}".of(section[""].through(this));
    }
  ],
  [ [ function(node) { return node.type === "para"; } ],
    function(para) {
      return "    <p>{*}</p>\r\n".of(para[""].through(this));
    }
  ],
  [ [ function(node) { return node.type === "note"; } ],
    function(note) {
      return '    <p class="note"><b>NOTE: </b>{*}</p>\r\n'.of(note[""].through(this));
    }
  ],
  [ [ function(node) { return node.emph; } ],
    function(emph) {
      return "<em>{emph}</em>".of(emph);
    }
  ]
] };

console.log(D1document.through(D1toHTML));

... 제공합니다 :

<html>
  <head>
    <title>
      Document Title
    </title>
  </head>
  <body>
    <h2>Chapter Title</h2>
    <h3>Section Title</h3>
    <p>This is a test.</p>
    <p class="note"><b>NOTE: </b>This is a note.</p>
    <h3>Another Section Title</h3>
    <p>This is <em>another</em> test.</p>
    <p class="note"><b>NOTE: </b>This is another note.</p>
  </body>
</html>

2. JSON에서 JSON으로 :

깡깡이: https://jsfiddle.net/YSharpLanguage/ppfmmu15/10

이 곳 :

// (A "Company" is just an object with a "Team")
function Company(obj) {
  return obj.team && Team(obj.team);
}

// (A "Team" is just a non-empty array that contains at least one "Member")
function Team(obj) {
  return ({ }.toString.call(obj) === "[object Array]") &&
         obj.length &&
         obj.find(function(item) { return Member(item); });
}

// (A "Member" must have first and last names, and a gender)
function Member(obj) {
  return obj.first && obj.last && obj.sex;
}

function Dude(obj) {
  return Member(obj) && (obj.sex === "Male");
}

function Girl(obj) {
  return Member(obj) && (obj.sex === "Female");
}

var data = { team: [
  { first: "John", last: "Smith", sex: "Male" },
  { first: "Vaio", last: "Sony" },
  { first: "Anna", last: "Smith", sex: "Female" },
  { first: "Peter", last: "Olsen", sex: "Male" }
] };

var TO_SOMETHING_ELSE = { $: [

  [ [ Company ],
    function(company) {
      return { some_virtual_dom: {
        the_dudes: { ul: company.team.select(Dude).through(this) },
        the_grrls: { ul: company.team.select(Girl).through(this) }
      } }
    } ],

  [ [ Member ],
    function(member) {
      return { li: "{first} {last} ({sex})".of(member) };
    } ]

] };

console.log(JSON.stringify(data.through(TO_SOMETHING_ELSE), null, 4));

... 제공합니다 :

{
    "some_virtual_dom": {
        "the_dudes": {
            "ul": [
                {
                    "li": "John Smith (Male)"
                },
                {
                    "li": "Peter Olsen (Male)"
                }
            ]
        },
        "the_grrls": {
            "ul": [
                {
                    "li": "Anna Smith (Female)"
                }
            ]
        }
    }
}

3. XSLT와 JavaScript :

자바 스크립트와 동등한 ...

XSLT 3.0 REC 섹션 14.4 예 : 공통 값을 기준으로 노드 그룹화

( http://jsfiddle.net/YSharpLanguage/8bqcd0ey/1에서 )

Cf. https://www.w3.org/TR/xslt-30/#grouping-examples

어디...

var cities = [
  { name: "Milano",  country: "Italia",      pop: 5 },
  { name: "Paris",   country: "France",      pop: 7 },
  { name: "München", country: "Deutschland", pop: 4 },
  { name: "Lyon",    country: "France",      pop: 2 },
  { name: "Venezia", country: "Italia",      pop: 1 }
];

/*
  Cf.
  XSLT 3.0 REC Section 14.4
  Example: Grouping Nodes based on Common Values

  https://www.w3.org/TR/xslt-30/#grouping-examples
*/
var output = "<table>\r\n\
  <tr>\r\n\
    <th>Position</th>\r\n\
    <th>Country</th>\r\n\
    <th>City List</th>\r\n\
    <th>Population</th>\r\n\
  </tr>{*}\r\n\
</table>".of
  (
    cities.select().groupBy("country")(function(byCountry, index) {
      var country = byCountry[0],
          cities = byCountry[1].select().orderBy("name");
      return "\r\n\
  <tr>\r\n\
    <td>{position}</td>\r\n\
    <td>{country}</td>\r\n\
    <td>{cities}</td>\r\n\
    <td>{population}</td>\r\n\
  </tr>".
        of({ position: index + 1, country: country,
             cities: cities.map(function(city) { return city.name; }).join(", "),
             population: cities.reduce(function(sum, city) { return sum += city.pop; }, 0)
           });
    })
  );

... 제공합니다 :

<table>
  <tr>
    <th>Position</th>
    <th>Country</th>
    <th>City List</th>
    <th>Population</th>
  </tr>
  <tr>
    <td>1</td>
    <td>Italia</td>
    <td>Milano, Venezia</td>
    <td>6</td>
  </tr>
  <tr>
    <td>2</td>
    <td>France</td>
    <td>Lyon, Paris</td>
    <td>9</td>
  </tr>
  <tr>
    <td>3</td>
    <td>Deutschland</td>
    <td>München</td>
    <td>4</td>
  </tr>
</table>

4. JSONiq 대 JavaScript :

자바 스크립트와 동등한 ...

JSONiq 사용 사례 섹션 1.1.2. JSON 그룹화 쿼리

( https://jsfiddle.net/YSharpLanguage/hvo24hmk/3에서 )

Cf. http://jsoniq.org/docs/JSONiq-usecases/html-single/index.html#jsongrouping

어디...

/*
  1.1.2. Grouping Queries for JSON
  http://jsoniq.org/docs/JSONiq-usecases/html-single/index.html#jsongrouping
*/
var sales = [
  { "product" : "broiler", "store number" : 1, "quantity" : 20  },
  { "product" : "toaster", "store number" : 2, "quantity" : 100 },
  { "product" : "toaster", "store number" : 2, "quantity" : 50 },
  { "product" : "toaster", "store number" : 3, "quantity" : 50 },
  { "product" : "blender", "store number" : 3, "quantity" : 100 },
  { "product" : "blender", "store number" : 3, "quantity" : 150 },
  { "product" : "socks", "store number" : 1, "quantity" : 500 },
  { "product" : "socks", "store number" : 2, "quantity" : 10 },
  { "product" : "shirt", "store number" : 3, "quantity" : 10 }
];

var products = [
  { "name" : "broiler", "category" : "kitchen", "price" : 100, "cost" : 70 },
  { "name" : "toaster", "category" : "kitchen", "price" : 30, "cost" : 10 },
  { "name" : "blender", "category" : "kitchen", "price" : 50, "cost" : 25 },
  {  "name" : "socks", "category" : "clothes", "price" : 5, "cost" : 2 },
  { "name" : "shirt", "category" : "clothes", "price" : 10, "cost" : 3 }
];

var stores = [
  { "store number" : 1, "state" : "CA" },
  { "store number" : 2, "state" : "CA" },
  { "store number" : 3, "state" : "MA" },
  { "store number" : 4, "state" : "MA" }
];

var nestedGroupingAndAggregate = stores.select().orderBy("state").groupBy("state")
( function(byState) {
    var state = byState[0],
        stateStores = byState[1];
    byState = { };
    return (
      (
        byState[state] =
        products.select().orderBy("category").groupBy("category")
        ( function(byCategory) {
            var category = byCategory[0],
                categoryProducts = byCategory[1],
                categorySales = sales.filter(function(sale) {
                  return stateStores.find(function(store) { return sale["store number"] === store["store number"]; }) &&
                         categoryProducts.find(function(product) { return sale.product === product.name; });
                });
            byCategory = { };
            return (
              (
                byCategory[category] =
                categorySales.select().orderBy("product").groupBy("product")
                ( function(byProduct) {
                    var soldProduct = byProduct[0],
                        soldQuantities = byProduct[1];
                    byProduct = { };
                    return (
                      (
                        byProduct[soldProduct] =
                        soldQuantities.reduce(function(sum, sale) { return sum += sale.quantity; }, 0)
                      ),
                      byProduct
                    );
                } ) // byProduct()
              ),
              byCategory
            );
        } ) // byCategory()
      ),
      byState
    );
} ); // byState()

... 제공합니다 :

[
  {
    "CA": [
      {
        "clothes": [
          {
            "socks": 510
          }
        ]
      },
      {
        "kitchen": [
          {
            "broiler": 20
          },
          {
            "toaster": 150
          }
        ]
      }
    ]
  },
  {
    "MA": [
      {
        "clothes": [
          {
            "shirt": 10
          }
        ]
      },
      {
        "kitchen": [
          {
            "blender": 250
          },
          {
            "toaster": 50
          }
        ]
      }
    ]
  }
]

JSONPath wrt의 한계를 극복하는 것도 유용합니다. 이 SO 질문에 의해 제기 된 조상 축에 대한 쿼리 (그리고 확실히 다른 사람들)에 .

예를 들어 브랜드 ID를 아는 식료품 품목의 할인을받는 방법

{
 "prods": [
    {
        "info": {
              "rate": 85
                },
        "grocery": [
                 {
                  "brand": "C",
                  "brand_id": "984"
                 },
                 {
                  "brand": "D",
                  "brand_id": "254"
                 }
                 ],
         "discount": "15"
    },
    {
        "info": {
              "rate": 100
                },
        "grocery": [
                 {
                  "brand": "A",
                  "brand_id": "983"
                 },
                 {
                  "brand": "B",
                  "brand_id": "253"
                 }
                 ],
         "discount": "20"
     }
 ]
}

?

가능한 해결책은 다음과 같습니다.

var products = {
     "prods": [
        {
            "info": {
                  "rate": 85
                    },
            "grocery": [
                     {
                      "brand": "C",
                      "brand_id": "984"
                     },
                     {
                      "brand": "D",
                      "brand_id": "254"
                     }
                     ],
             "discount": "15"
        },
        {
            "info": {
                  "rate": 100
                    },
            "grocery": [
                     {
                      "brand": "A",
                      "brand_id": "983"
                     },
                     {
                      "brand": "B",
                      "brand_id": "253"
                     }
                     ],
             "discount": "20"
         }
     ]
};

function GroceryItem(obj) {
  return (typeof obj.brand === "string") && (typeof obj.brand_id === "string");
}

    // last parameter set to "true", to grab all the "GroceryItem" instances
    // at any depth:
var itemsAndDiscounts = [ products ].nodeset(GroceryItem, true).
    map(
      function(node) {
        var item = node.value, // node.value: the current "GroceryItem" (aka "$.prods[*].grocery[*]")

            discount = node.parent. // node.parent: the array of "GroceryItem" (aka "$.prods[*].grocery")
                       parent. // node.parent.parent: the product (aka "$.prods[*]")
                       discount; // node.parent.parent.discount: the product discount

        // finally, project into an easy-to-filter form:
        return { id: item.brand_id, discount: discount };
      }
    ),
    discountOfItem983;

discountOfItem983 = itemsAndDiscounts.
  filter
  (
    function(mapped) {
      return mapped.id === "983";
    }
  )
  [0].discount;

console.log("Discount of #983: " + discountOfItem983);

... 다음을 제공합니다.

Discount of #983: 20

'HTH,


10

지금 있습니다! 최근 에이 목적을 위해 json-transforms 라이브러리를 만들었습니다 .

https://github.com/ColinEberhardt/json-transforms

JSPath 의 조합을 사용합니다.XPath에서 모델링 된 DSL 와 XSLT에서 직접 영감을 얻은 재귀 패턴 일치 접근 방식 .

다음은 간단한 예입니다. 다음과 같은 JSON 객체가 제공됩니다.

const json = {
  "automobiles": [
    { "maker": "Nissan", "model": "Teana", "year": 2011 },
    { "maker": "Honda", "model": "Jazz", "year": 2010 },
    { "maker": "Honda", "model": "Civic", "year": 2007 },
    { "maker": "Toyota", "model": "Yaris", "year": 2008 },
    { "maker": "Honda", "model": "Accord", "year": 2011 }
  ]
};

변형은 다음과 같습니다.

const jsont = require('json-transforms');
const rules = [
  jsont.pathRule(
    '.automobiles{.maker === "Honda"}', d => ({
      Honda: d.runner()
    })
  ),
  jsont.pathRule(
    '.{.maker}', d => ({
      model: d.match.model,
      year: d.match.year
    })
  ),
  jsont.identity
];

const transformed  = jsont.transform(json, rules);

다음과 같은 출력 :

{
  "Honda": [
    { "model": "Jazz", "year": 2010 },
    { "model": "Civic", "year": 2007 },
    { "model": "Accord", "year": 2011 }
  ]
}

이 변환은 세 가지 규칙으로 구성됩니다. 첫 번째는 Honda가 만든 모든 자동차와 일치하여 Honda속성을 가진 객체를 방출 한 다음 재귀 적으로 일치시킵니다. 두 번째 규칙은 객체와 maker속성을 일치 시켜 modelyear속성을 출력합니다 . 마지막은 재귀 적으로 일치하는 항등 변환입니다.


9

오래된 질문에 대한 또 다른 새로운 답변으로 DefiantJS를 살펴 보십시오 . 그것은 XSLT의 아니다 동등한 은, JSON에 대한 것입니다 JSON에 대한 XSLT. 문서의 "템플릿"섹션에는 다음 예제가 포함되어 있습니다.

<!-- Defiant template -->
<script type="defiant/xsl-template">
    <xsl:template name="books_template">
        <xsl:for-each select="//movie">
            <xsl:value-of select="title"/><br/>
        </xsl:for-each>
    </xsl:template>
</script>

<script type="text/javascript">

var data = {
        "movie": [
            {"title": "The Usual Suspects"},
            {"title": "Pulp Fiction"},
            {"title": "Independence Day"}
        ]
    },
    htm = Defiant.render('books_template', data);

console.log(htm);
// The Usual Suspects<br>
// Pulp Fiction<br>
// Independence Day<br>

5

나는 엄청난 양의 JavaScript 템플릿 엔진과 모든 인라인 HTML 템플릿, 다른 마크 업 스타일 등에 정말 지쳤 으며 JSON 데이터 구조에 XSLT 형식을 사용할 수 있는 작은 라이브러리만들기 로 결정했습니다 . 어떤 식 으로든 로켓 과학이 아닙니다 .JSON은 XML로 구문 분석 한 다음 XSLT 문서로 형식화되었습니다. Chrome의 JavaScript 템플릿 엔진만큼 빠르지는 않지만 대부분의 다른 브라우저에서는 더 큰 데이터 구조를위한 JS 엔진 대안만큼 빠릅니다.


4

Camel route umarshal (xmljson)-> to (xlst)-> marshal (xmljson)을 사용하고 있습니다. Camel을 이미 사용하고 있다면 충분히 효율적이지만 (100 % 완벽하지는 않지만) 간단합니다.


3

JSONiq 는 그러한 표준이며 Zorba 는 오픈 소스 C ++ 구현입니다. JSON을 기본 데이터 유형으로 추가하여 JSONiq을 XQuery로 볼 수도 있습니다.



2

Yate ( https://github.com/pasaran/yate )는 XSLT를 위해 특별히 설계되었으며 JPath (JS와 동등한 XPath 기능)를 제공하며 JavaScript로 컴파일되며 프로덕션 사용 내역이 있습니다. 실제로 문서화되어 있지 않지만 샘플과 테스트를 읽는 것으로 충분합니다.


2

JSLT 는 XSLT와 동등한 JSON에 매우 가깝습니다. 출력의 고정 부분을 JSON 구문으로 작성한 다음 표현식을 삽입하여 템플리트에 삽입하려는 값을 계산하는 변환 언어입니다.

예를 들면 :

{
  "time": round(parse-time(.published, "yyyy-MM-dd'T'HH:mm:ssX") * 1000),
  "device_manufacturer": .device.manufacturer,
  "device_model": .device.model,
  "language": .device.acceptLanguage
}

Jackson 위에 Java로 구현되었습니다.


0

확실하지 않은 것은 이것에 대한 필요성이며, 도구가 부족하다는 것은 필요가 없다는 것을 의미합니다. JSON은 객체로 처리하는 것이 가장 좋으며 (JS에서 수행되는 방식) 일반적으로 객체 자체의 언어를 사용하여 변형 (JSON에서 만든 Java 객체의 Java, Perl, Python, Perl, c #, PHP 등) 의 위에). 정상적인 할당 (또는 설정, 가져 오기), 반복 등으로.

XSLT는 다른 언어 일 뿐이므로 XML은 객체 표기법이 아니므로 프로그래밍 언어의 객체가 정확히 맞지 않기 때문입니다 (계층 XML 모델과 객체 / 구조 사이의 임피던스).


Facebook이 XML에서 Json으로 변환 한 후에 필자는 이와 같은 도구가 절실히 필요합니다.
Joe Soul-bringer

어떤 유스 케이스를 생각하고 있습니까? XML 응답을 HTML로 렌더링하는 방식과 비슷한 JSON 콘텐츠를 렌더링 할 수 있습니까? 아니면 다른 것?
StaxMan

XSLT 유형 방법을 사용하는 것과 비교하여 프로그래밍 방식의 객체 방식 (루핑, 필요에 따라 분기 등)을 JSON 변환으로 처리하는 것이 얼마나 쉬운 지 궁금합니다. 특히 대규모 JSON 객체를 변환하고 소스 JSON의 일부 데이터가 이동하는 경우 대상 JSON의 일부 노드 (위로 구조의 직접 사본이 아님)를 위 / 아래로 이동하고 소스 또는 대상 JSON의 특정 노드가 JSON 내의 객체 배열의 일부이고 다른 JSON (소스 / 대상)이 아닌 경우 .
David

용이함은 매우 주관적이므로 그 중 많은 부분이 익숙한 것과 관련이 있다고 생각합니다.
StaxMan

JSON 변환이 반드시 필요하지만 JS가 대부분 충족합니다. :-) 그러나 jq- 가볍고 유연한 명령 줄 JSON 프로세서를 보셨습니까 ? 특히 JS를 사용할 수없는 경우에 적합합니다. JS보다 변형이 훨씬 쉽고 직관적이라고 말할 수 있습니다. 예를 들면 필드를 추출 name하고 address, 및 배열에 넣어 :[.name, .address]
13ren

0

Mr. Data Coverter를 사용하여 JSON을 XML로 변환 하고 XSLT를 사용하여 변환 한 다음 동일한 것을 사용하여 다시 JSON으로 변경하십시오.


1
코드가 좋은 성능을 발휘하도록하려면 옵션이 아닙니다.
orad

0

XSLT의 일치하는 표현식 및 재귀 템플릿 뒤에 친숙하고 선언적인 패턴과 함께 순수한 JavaScript를 사용하는 접근 방식의 개념에 대한 낙서 / 증거에 대해서는 다음을 참조하십시오. https://gist.github.com/brettz9/0e661b3093764f496e36을 하십시오.

(JSON에도 비슷한 접근 방식이 적용될 수 있습니다.)

데모는 Firefox에서 템플릿을 표현할 때 편의를 위해 JavaScript 1.8 표현식 클로저에 의존합니다 (적어도 메소드의 ES6 짧은 형식이 구현 될 때까지).

면책 조항 : 이것은 내 자신의 코드입니다.


0

오래 전에 잭슨 기반 json 처리 프레임 워크 용 dom 어댑터를 작성했습니다. nu.xom 라이브러리를 사용합니다. 결과 dom 트리는 java xpath 및 xslt 기능과 함께 작동합니다. 꽤 간단한 구현 방법을 선택했습니다. 예를 들어 루트 노드는 항상 "루트"라고하며, 배열은 html과 같이 li 하위 요소가있는 ol 노드로 이동하고 다른 모든 것은 기본 값 또는 다른 객체 노드가있는 하위 노드 일뿐입니다.

JsonXmlConverter.java

용법: JsonObject sampleJson = sampleJson(); org.w3c.dom.Document domNode = JsonXmlConverter.getW3cDocument(sampleJson, "root");


0

아직 제공되지 않은 방법 중 하나는 파서 생성기를 사용하여 JSON을 구문 분석하고 XML 출력을 생성하는 파서를 생성하는 XSLT입니다.

XML 회의에서 많이 언급되는 한 가지 옵션은 ReX 파서 생성기 ( http://www.bottlecaps.de/rex/ )입니다. 사이트에 완전히 문서화되어 있지는 않지만 검색시 레시피를 사용할 수 있습니다.


0

XSLT를 JSON과 함께 사용할 수 있습니다. XPath (3.1)의 Verson 3 XSLT (3.0) 및 XQuery (3.1)는 어떤 방식 으로든 JSON을 지원합니다. 이것은 Saxon의 상용 버전에서 사용 가능한 것으로 보이며 어느 시점에서 HE 버전에 포함될 수 있습니다. https://www.saxonica.com/html/documentation/functions/fn/parse-json.html

-

대체 솔루션에서 기대할 수있는 것 :

일치하는 데이터 세트를 가져 오기 위해 JSON을 입력하고 JSON 또는 TEXT를 출력하고 싶습니다.

임의의 속성에 액세스하고 값을 평가

조건부 논리 지원

변형 스크립트가 도구 외부, 텍스트 기반, 일반적으로 일반적으로 사용되는 언어가되기를 원합니다.

잠재적 대안?

SQL이 적합한 대안이 될 수 있는지 궁금합니다. https://docs.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server

대체 도구가 JSON 및 XML을 처리 할 수 ​​있다면 좋을 것입니다 https://docs.microsoft.com/en-us/sql/relational-databases/xml/openxml-sql-server

사용하는 XSLT 스크립트를 SQL로 변환하려고 시도하지 않았거나이 옵션을 아직 완전히 평가하지 않았지만 더 빨리 조사하기를 희망합니다. 지금까지 몇 가지 생각.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.