JSON için XSLT eşdeğeri [kapalı]


411

JSON için bir XSLT eşdeğeri var mı ? XSLT'nin XML'e yaptığı gibi JSON'da dönüşümler yapmama izin veren bir şey.


1
Btw, bu hangi dilde / platformda olurdu?
StaxMan

6
@StaxMan XSLT, birçok dilde ve platformda gerçek uygulamaları olan bir standarttır, sorularım da benzer bir çabayı hedefliyor.
luvieere

36
Sorunuz için +1. Birçok kişi XSLT'yi gözden kaçırıyor ya da beğenmiyor gibi görünüyor, ancak bu XML ayrıntısına bir tepki olabilir. Ve aslında, XML yavaş yavaş lehine düştüğü için, üzücü olan XSLT'yi kullanmak için gittikçe daha az fırsat var! JSON için bir XSLT eşdeğeri harika olurdu.
Nicolas Le Thierry d'Ennequin

10
@ NicolasLeThierryd'Ennequin Anlaştı. Birçok kişi XML'den nefret eder ve bu nedenle XSLT'yi reddeder. Araçların XML ekosistemi, daha da fazla insanı geri çeviren Java geliştiricileri üzerinde ağırdır. Ama 2000'li yılların ortalarında XSLT'de ağırdım ve XML ekosisteminin dışında doğrudan eşdeğeri olmayan muazzam bir güç var. Ben ediyorum aşk JSON eşdeğer!
Zearin

Yanıtlar:


77

İlginç fikir. Google'da yapılan bazı aramalar, aşağıdakiler dahil olmak üzere birkaç sayfa ilgi alanı oluşturdu:

Bu yardımcı olur umarım.


10
Evet, teşekkürler, aradığım şey buydu. Tekniğin daha popüler olmaması üzücü, JSON genellikle REST tarzı hizmetlerde bir dönüş biçimi olarak kullanılıyor ve buna dönüşümleri uygulamak için standart bir yol olması güzel olurdu.
luvieere

8
Bu kod string.eval () ... :-(
dreftymac

Yalnızca cevabı bağla
Jean-François Fabre

102

JSON için XSLT eşdeğerleri - adayların listesi (araçlar ve teknik özellikler)

Araçlar

  1. XSLT

    Sen kullanabilirsiniz JSON için XSLT'yi amacı ile json-to-xml: fn .

    Bu bölümde, JSON verilerinin XSLT kullanılarak işlenmesine izin veren özellikler açıklanmaktadır.

  2. jq

    jq, JSON verileri için sed gibidir - bunu, sed, awk, grep ve arkadaşlarının metinle oynamanıza izin verdiği aynı kolaylıkla dilimlemek ve filtrelemek ve haritalamak ve dönüştürmek için kullanabilirsiniz. Farklı işletim sistemleri için yükleme paketleri vardır.

  3. jj

    JJ, JSON belgelerinden değerleri almak veya güncellemek için hızlı ve basit bir yol sağlayan bir komut satırı yardımcı programıdır. Kaputun altında GJSON ve SJSON tarafından desteklenmektedir.

  4. fx

    Komut satırı JSON işleme aracı

    • Yeni sözdizimi öğrenmenize gerek yok
    • Düz JavaScript
    • Biçimlendirme ve vurgulama
    • Bağımsız ikili
  5. jl

    jl ("JSON lambda"), JSON'u sorgulamak ve değiştirmek için kullanılan küçük bir işlevsel dildir.

  6. SARSINTI

    Java için yazılmış JSON'dan JSON'a dönüştürme kütüphanesi; burada dönüşüm için "belirtimin" kendisi JSON belgesidir.

  7. gron

    JSON'u açgözlü yap! gron, istediklerinizi grep etmeyi ve ona giden mutlak 'yolu' görmeyi kolaylaştırmak için JSON'u ayrık atamalara dönüştürür. JSON'un büyük lekelerini döndüren ancak korkunç belgelere sahip API'lerin keşfini kolaylaştırır.

  8. json

    json, JSON ile çalışmak için hızlı bir CLI aracıdır. Harici bir bölümü olmayan (node.js dışında) tek dosyalı bir node.js betiğidir.

  9. json-E

    JSON-e, bağlamı JSON nesnelerine gömmek için kullanılan bir veri yapısı parametreleme sistemidir. Ana fikir, bir veri yapısını bir "şablon" olarak ele almak ve başka bir veri yapısını bağlam olarak kullanarak bir çıktı veri yapısı üretmek üzere dönüştürmektir.

  10. JSLT

    JSLT, JSON için eksiksiz bir sorgulama ve dönüştürme dilidir. Dil tasarımı jq, XPath ve XQuery'den esinlenmiştir.

  11. JSONata

    JSONata, JSON verileri için hafif bir sorgulama ve dönüştürme dilidir. XPath 3.1'in 'konum yolu' semantiğinden esinlenerek, karmaşık sorguların kompakt ve sezgisel bir gösterimde ifade edilmesini sağlar.

  12. json-transforms Son İşlem 1 Aralık 2017

    JSON verilerinin dönüştürülmesi için özyinelemeli, kalıp eşleştirme yaklaşımı sağlar. Dönüşümler, bir JSON nesnesinin yapısıyla eşleşen bir kurallar kümesi olarak tanımlanır. Bir eşleşme gerçekleştiğinde, kural dönüştürülen verileri yayar, isteğe bağlı olarak alt nesneleri dönüştürmek için yinelenir.

  13. jsawk Son taahhüt 4 Mar 2015

    Jsawk garip gibi, ama JSON için. Stdin'den okunan bir dizi JSON nesnesi ile çalışırsınız, stdout'a yazdırılan bir sonuç dizisi oluşturmak için bunları JavaScript kullanarak filtreleyin.

  14. Bölüm 13 Nis 2017

    Testler docu olarak kullanılabilir https://github.com/pasaran/yate/tree/master/tests

  15. jsonpath-object-transform Son Gönderi 18 Oca 2017

    JSONPath kullanarak nesne değişmezinden veri alır ve şablona dayalı yeni nesneler oluşturur.

  16. Bölüm Stapling Last Command 16 Eylül 2013

    Zımbalama, JSON nesneleri için XSLT biçimlendirmesini sağlayan bir JavaScript kitaplığıdır. JavaScript şablonlama motoru ve metin / html şablonları kullanmak yerine Zımbalama, JSON veri kaynaklarınızı ayrıştırmak için Ajax ile eşzamansız olarak yüklenen ve daha sonra istemci tarafı önbelleğe alınan XSLT şablonlarını kullanma fırsatı verir.

Özellikleri:

  • JsonPointer

    JSON İşaretçisi, bir JavaScript Nesne Gösterimi (JSON) belgesinde belirli bir değeri tanımlamak için bir dize sözdizimi tanımlar.

  • JsonPath

    JSONPath ifadeleri, her zaman bir XML belgesiyle birlikte kullanıldığında XPath ifadesiyle aynı şekilde bir JSON yapısına işaret eder

  • JSPath

    JSON için JSPath XML için XPath gibidir. "

  • JSONiq

    JSONiq'in arkasındaki ana ilham kaynağı, yarı yapılandırılmış veriler için şimdiye kadar başarılı ve üretken bir sorgulama dilinin kanıtlandığı XQuery'dir.


2
Çok ayrıntılı ve faydalı yazınız için teşekkür ederiz. Tek satırlı json'u okunabilir bir forma dönüştürmek için jq (listenizdeki nr.2) benim için en iyi seçimdir. Tekrar teşekkürler!
Ocak 1919'da primehunter

1
Sık sık güzel baskı için json_pp kullanıyorum . Birçok dağıtım için kullanılabilir.
jschnasse

70

JOLT'u deneyin . Java ile yazılmış bir JSON JSON dönüşüm kütüphanesidir.

Özellikle "JSON -> XML -> XSLT -> XML -> JSON" oyununu oynamak istemediğimiz için oluşturuldu ve yeterince karmaşık bir dönüşüm için bir şablon kullanmak sürdürülemez.


4
+9000: Bu ciddi bir proje! Hurra. Örneklerle çevrimiçi demo, öğrenme eğrisine tırmanmaya büyük ölçüde yardımcı olur: jolt-demo.appspot.com
kevinarpe

15

jq - hafif ve esnek komut satırı JSON işlemci

XSLT gibi şablon tabanlı değil, daha özlü. örneğin bir diziye alan nameve addressalanları çıkarmak için:[.name, .address]

Öğretici heyecan JSON API transforme bir örnek yürür (ve el pek çok örnek vardır).


4
Daha özlü çünkü çok daha az yetenekli.
Ihe Onwuka

Bir Json ağacında belirli bir özniteliği özyinelemeli olarak nasıl arayacağımı bulamadım
Daniel

@Daniel .. | .attr_name?aradığın şey mi? ( stedolan.github.io/jq/manual/#RecursiveDescent: .. )
ankostis

1
Belki XSLT kadar yetenekli değil ama çok kullanışlı ve XSLT kadar karmaşık değil
flq

15

XSLT, http://www.w3.org/TR/xslt-30/#json adresinde görüldüğü gibi JSON'u destekler

XML, sınırlayıcı belirteçleri için köşeli parantez kullanır, JSON parantez, köşeli parantez, ... I. e. XML'in daha az belirteç tanıma karşılaştırması, bildirimsel dönüşüm için optimize edildiği anlamına gelirken, hız nedenleriyle anahtar ifadesi gibi daha fazla karşılaştırma, komut dosyası dillerinde zorunlu kodun yararlı olduğu spekülatif dal tahminini varsayar. Doğrudan sonuç olarak, farklı yarı yapılandırılmış veri karışımları için, duyarlı sayfaların bir parçası olarak XSLT ve javascript motorlarının performansını karşılaştırmak isteyebilirsiniz. İhmal edilebilir veri yükü için, dönüşümler XML serileştirmesi olmayan JSON ile de işe yarayabilir. W3'ün kararı daha iyi analize dayanmalıdır.


15

Geçenlerde JSON'u şekillendirmeyi sevdiğim bir araç buldum: https://github.com/twigkit/tempo . Kullanımı çok kolay bir araç - bence, XSLT'den çalışmak çok daha kolay - XPATH sorgularına gerek yok.


9
Dönüşümün nihai sonucu HTML ise Tempo harika görünüyor. Ancak, zımni bir yapıyı farklı bir yapıya yeniden düzenlemek istiyorsanız, ancak sonuç hala JSON'dur. Dönüşümün işlevsel bir şekilde yazabilmesi için hala XPath analogu istiyorum.
Toddius Zho

1
Tempo gerçekten çok teşekkür ederim. Ancak tarayıcıya bir xml ve bir xslt (<? Xsl-stylesheet>) gönderebilirsiniz ve tarayıcınız xslt'yi xml'e uygular ve xml'inizin tanımlanmış bir görünümünü başka bir kod olmadan gösterir. Bu jsonT / tempo için de geçerli olmalıdır.
Martin Meeser


11

Araç eksikliğinin, ihtiyaç eksikliğinin sadece yalvarmak olduğunu öne sürdüğünü söylemek. Aynı şey Linux'ta X veya Y'yi desteklemek için de uygulanabilir (Neden böyle bir azınlık işletim sistemi için kaliteli sürücüler ve / veya oyunlar geliştirmekten rahatsız oluyorsunuz? Ve neden büyük oyun ve donanım şirketlerinin geliştirmediği bir işletim sistemine dikkat edin?). Muhtemelen XSLT ve JSON kullanması gereken insanlar biraz önemsiz bir çözüm kullanıyor: JSON'u XML'e dönüştürme. Ama bu en uygun çözüm değil, değil mi?

Yerel bir JSON biçiminiz varsa ve tarayıcıda "wysywyg" biçimini düzenlemek istediğinizde, XSLT, sorun için yeterli bir çözüm olabilir. Bunu geleneksel javascript programlama ile yapmak eşek için bir ağrı olabilir.

Aslında, XSLT'ye "taş devri" yaklaşımını uyguladım, javascript için bir şablon çağırmak, çocukları işlemek, vb. Gibi bazı temel komutları yorumlamak için alt dize ayrıştırma özelliğini kullandım. XSLT'yi ayrıştırmak için tam teşekküllü bir XML ayrıştırıcısı uygulamak. Sorun, bir JSON nesnesini dönüştürmek için XML şablonlarını kullanmak için şablonların XML'sini ayrıştırmanız gerektiğidir.

Bir JSON nesnesini XML (veya HTML veya metin ya da her neyse) ile değiştirmek için sözdizimi ve dönüştürme komutlarını tanımlamak için hangi özel karakterleri kullanmanız gerektiğini dikkatlice düşünmeniz gerekir. Aksi takdirde, kendi özel şablonlama diliniz için bir ayrıştırıcı tasarlamanız gerekir. Bu yolda yürüdükten sonra, bunun güzel olmadığını söyleyebilirim.

Güncelleme (12 Kasım 2010): Ayrıştırıcımda birkaç hafta çalıştıktan sonra, onu optimize edebildim. Şablonlar önceden ayrıştırılır ve komutlar JSON nesneleri olarak saklanır. Dönüşüm kuralları da JSON nesneleridir, şablon kodu ise HTML ve kabuk koduna benzer bir homebrew sözdizimi karışımıdır. Bir belge düzenleyicisi yapmak için karmaşık bir JSON belgesini HTML'ye dönüştürebildim. Kod, editör için yaklaşık 1K satırdır (özel bir proje içindir, bu yüzden paylaşamam) ve JSON dönüşüm kodu için 990 satır (yineleme komutları, basit karşılaştırmalar, şablon çağırma, değişken kaydetme ve değerlendirme içerir). Bunu bir MIT lisansı altında bırakmayı planlıyorum. Katılmak istiyorsanız bana bir posta bırakın.


11

Yakın zamanda kendi küçük kütüphanemi yazdım.

5.1 İşleme Modeli (XSLT REC) https://www.w3.org/TR/xslt#section-Processing-Model

mümkün olduğunca (zaten yapabildiğim gibi), birkaç JavaScript kodu satırında.

İşte önemsiz olmayan birkaç kullanım örneği ...

1. JSON'dan bazılarına işaretleme:

Keman: https://jsfiddle.net/YSharpLanguage/kj9pk8oz/10

( D.1 Belge Örneği'nden ilham alınmıştır (XSLT REC) https://www.w3.org/TR/xslt#section-Document-Example )

nerede bu:

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));

... verir:

<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>

ve

2. JSON'dan JSON'a:

Keman: https://jsfiddle.net/YSharpLanguage/ppfmmu15/10

nerede bu:

// (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));

... verir:

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

3. XSLT ve JavaScript karşılaştırması:

JavaScript eşdeğeri ...

XSLT 3.0 REC Bölüm 14.4 Örnek: Düğümleri Ortak Değerlere Göre Gruplama

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

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

nerede...

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)
           });
    })
  );

... verir:

<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 ve JavaScript karşılaştırması:

JavaScript eşdeğeri ...

JSONiq Kullanım Durumları Bölüm 1.1.2. JSON için Sorguları Gruplama

(şurada: https://jsfiddle.net/YSharpLanguage/hvo24hmk/3 )

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

nerede...

/*
  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()

... verir:

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

JSONPath wrt'nin sınırlamalarının üstesinden gelmek de yararlıdır. bu SO sorusu tarafından ortaya konulduğu üzere, ata eksenine karşı sorgulama (ve kesinlikle diğerleri) .

Örneğin, markasının kimliğini bilen bir bakkal ürününün indirimini nasıl alacağınız,

{
 "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"
     }
 ]
}

?

Olası bir çözüm:

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);

... ki:

Discount of #983: 20

'HTH,


10

Şimdi var! Son zamanlarda tam olarak bu amaçla bir kütüphane, json-transforms oluşturdum :

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

JSPath'in bir kombinasyonunu kullanır , XPath üzerinde modellenmiş bir DSL ve yinelemeli desen eşleştirme yaklaşımının .

İşte kısa bir örnek. Aşağıdaki JSON nesnesi verildiğinde:

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 }
  ]
};

İşte bir dönüşüm:

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);

Aşağıdaki çıktı hangi:

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

Bu dönüşüm üç kuraldan oluşur. Birincisi, Honda tarafından üretilen, bir Hondamülke sahip bir nesne yayan , daha sonra tekrarlayan bir şekilde eşleşen herhangi bir otomobille eşleşir . İkinci kural maker, modelve yearözelliklerinin çıktısını alan herhangi bir nesneyle eşleşir . Son, özyinelemeli olarak eşleşen kimlik dönüşümüdür.


9

Eski bir soruya yeni bir cevap olarak DefiantJS'ye bir göz atmanızı öneririm . JSON için bir XSLT eşdeğeri değil , JSON için XSLT. Dokümantasyonun "Şablon" bölümü bu örneği içerir:

<!-- 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

Orada çok sayıda JavaScript şablon motoru ve tüm satır içi HTML şablonları, farklı biçimlendirme stilleri, vb gerçekten bıktım ve JSON veri yapıları için XSLT biçimlendirme sağlayan küçük bir kütüphane inşa etmeye karar verdim . Hiçbir şekilde roket bilimi değil - sadece JSON XML'e ayrıştırıldı ve sonra bir XSLT belgesi ile biçimlendirildi. Hızlıdır, Chrome'daki JavaScript şablon motorları kadar hızlı değildir, ancak diğer tarayıcıların çoğunda en azından daha büyük veri yapıları için JS motoru alternatifi kadar hızlıdır.


4

Deve yolu umarshal (xmljson) -> to (xlst) -> mareşal (xmljson) kullanıyorum. Yeterince verimli (% 100 mükemmel olmasa da), ancak zaten Camel kullanıyorsanız basit.


3

JSONiq böyle bir standarttır ve Zorba açık kaynaklı bir C ++ uygulamasıdır. JSONiq, yerel veri türü olarak JSON ekleyerek XQuery olarak da görülebilir.



2

Yate ( https://github.com/pasaran/yate ), XSLT'den sonra özel olarak tasarlanmıştır, JPath (JS için doğal bir XPath eşdeğeri), JavaScript için derlenir ve oldukça fazla üretim geçmişi vardır. Pratik olarak belgelenmemiştir, ancak örnekler ve testler yoluyla okumak yeterli olmalıdır.


2

JSLT , XSLT'nin JSON eşdeğerine çok yakındır. Çıktının sabit kısmını JSON sözdiziminde yazdığınız ve sonra şablona eklemek istediğiniz değerleri hesaplamak için ifadeler eklediğiniz bir dönüştürme dilidir.

Bir örnek:

{
  "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'ın üstünde Java ile uygulanmaktadır.


0

Buna ihtiyaç duyulmadığından emin değilim ve bana göre araç eksikliği ihtiyaç eksikliğini gösteriyor. JSON en iyi nesne olarak işlenir (yine de JS'de nasıl yapılır) ve genellikle dönüşüm yapmak için nesnelerin dilini kullanırsınız (JSON'dan oluşturulan Java nesneleri için Java, Perl, Python, Perl, c #, PHP vb. ) üzerinde. Sadece normal atamalar (veya set, get), döngü vb.

Yani, XSLT sadece başka bir dildir ve gerekli olmasının bir nedeni de XML'in bir nesne gösterimi olmaması ve bu nedenle programlama dillerinin nesnelerinin tam uyması (hiyerarşik xml modeli ile nesneler / yapılar arasındaki empedans) olmamasıdır.


Facebook XML'den Json'a dönüştükten sonra, umutsuzca böyle bir araca ihtiyacım var.
Joe Soul getirici

Hangi kullanım durumunu düşünüyorsun? JSON içeriğini XML yanıtlarını HTML olarak nasıl oluşturacağınıza benzer hale getirebiliyor mu? Yoksa farklı bir şey mi?
StaxMan

Özellikle büyük JSON nesnesinin dönüştürülmesi ve kaynak JSON'daki bazı verilerin kayması durumunda, JSL dönüşümünü programlı nesne yolu (w / döngü, gerektiğinde dallanma vb.) Vs XSLT türü yöntemini kullanmanın ne kadar kolay olacağını merak ediyorum. hedef JSON'daki bazı düğümleri yukarı / aşağı (böylece yapının doğrudan bir kopyası değil) ve kaynak veya hedef JSON'daki belirli bir düğümün JSON içindeki nesne dizisinin bir parçası olduğunu ve diğer JSON'un (kaynak / hedef) olmadığını söyleyin .
David

Kolaylığı çok özneldir, bu yüzden çoğunun alışık olduğu şeyle ilgisi olduğundan şüpheleniyorum.
StaxMan

Kesinlikle JSON dönüşümü için bir ihtiyaç olsa da, haklı olarak büyük ölçüde JS tarafından karşılanıyor. :-) Ama jq - hafif ve esnek komut satırı JSON işlemci gördünüz mü? Özellikle JS mevcut olmadığında. Dönüşümün JS'den bile daha kolay ve sezgisel olduğunu söyleyebilirim. mesela alanları elde etmek nameve addressve bir dizi koydu:[.name, .address]
13ren

0

Neden Bay Data Coverter'ı kullanarak JSON'u XML'e dönüştürmüyorsunuz , XSLT'yi kullanarak dönüştürün ve ardından bunu kullanarak tekrar JSON'a dönüştürmüyorsunuz.


1
Kodunuzun sizin için iyi bir performansla yapmasını istiyorsanız bu bir seçenek değildir.
orad

0

XSLT'nin eşleşen ifadelerinin ve özyinelemeli şablonların arkasındaki tanıdık ve bildirimsel desenle birlikte saf JavaScript'i kullanma yaklaşımının çalışma doodle / kanıt kanıtı için bkz. Https://gist.github.com/brettz9/0e661b3093764f496e36

(Benzer bir yaklaşım JSON için de uygulanabilir.)

Demo, Firefox'ta şablonların ifade edilmesinde kolaylık sağlamak için JavaScript 1.8 ifade kapanmalarına da dayanmaktadır (en azından yöntemler için ES6 kısa formu uygulanana kadar).

Feragatname: Bu benim kendi kodum.


0

Uzun zaman önce jackson tabanlı json işleme çerçevem ​​için bir dom adaptörü yazdım. Nu.xom kütüphanesini kullanır. Ortaya çıkan dom ağacı, java xpath ve xslt tesisleri ile çalışır. Oldukça basit bazı uygulama seçimleri yaptım. Örneğin, kök düğüme her zaman "kök" denir, diziler li alt elemanları (html'de olduğu gibi) olan bir ol düğümüne gider ve diğer her şey sadece ilkel bir değere veya başka bir nesne düğümüne sahip bir alt düğümdür.

JsonXmlConverter.java

Kullanımı: JsonObject sampleJson = sampleJson(); org.w3c.dom.Document domNode = JsonXmlConverter.getW3cDocument(sampleJson, "root");


0

Henüz verilmeyen bir yaklaşım, XSLT'de JSON'ı ayrıştıran ve bir XML çıktısı üreten bir ayrıştırıcı oluşturmak için bir ayrıştırıcı oluşturucu kullanmaktır.

XML konferanslarında çok fazla bahsedilen bir seçenek ReX ayrıştırıcı üretecidir ( http://www.bottlecaps.de/rex/ ) - sitede tamamen belgelenmemiş olsa da, aramalarda tarifler mevcuttur.


0

XSLT'yi JSON ile kullanmak mümkün olabilir. XPath (3.1) XSLT (3.0) ve XQuery (3.1) 'den Verson 3, JSON'u bir şekilde destekler. Bu, Saxon'un ticari versiyonunda mevcut gibi görünüyor ve bir noktada HE versiyonuna dahil edilebilir. https://www.saxonica.com/html/documentation/functions/fn/parse-json.html

-

Alternatif bir çözümden ne beklenir:

Eşleşen bir veri kümesi almak ve JSON veya TEXT çıktı için JSON giriş yapabilmek istiyorum.

Rasgele özelliklere erişin ve değerleri değerlendirin

Koşullu mantık desteği

Dönüşüm komut dosyalarının araçtan harici, metin tabanlı ve tercihen sık kullanılan bir dil olmasını isterim.

Potansiyel alternatif?

SQL uygun bir alternatif olup olmadığını merak ediyorum. https://docs.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server

Alternatif aracın JSON ve XML'yi işleyebilmesi iyi olur https://docs.microsoft.com/en-us/sql/relational-databases/xml/openxml-sql-server

Henüz kullandığım XSLT betiklerini SQL'e dönüştürmeyi denemedim veya bu seçeneği henüz tam olarak değerlendirmedim, ancak daha yakında bakmayı umuyorum. Şimdiye kadar sadece bazı düşünceler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.