XSLT เทียบเท่ากับ JSON [ปิด]


411

คือมีXSLTเทียบเท่า JSON? บางสิ่งที่ทำให้ฉันสามารถทำการแปลงบน JSON อย่าง XSLT ทำกับ XML


1
Btw ภาษานี้ / แพลตฟอร์มจะเป็นใน?
StaxMan

6
@StaxMan XSLT เป็นมาตรฐานที่มีการใช้งานจริงในหลายภาษาและแพลตฟอร์มคำถามของฉันมีเป้าหมายความพยายามที่คล้ายกัน
luvieere

36
+1 สำหรับคำถามของคุณ คนจำนวนมากดูเหมือนจะมองข้ามหรือไม่ชอบ XSLT แต่อาจเป็นเพียงปฏิกิริยาตอบสนองต่อการ verbosity XML และแน่นอนว่าเมื่อ XML ค่อย ๆ หลุดจากความโปรดปรานมีโอกาสน้อยลงที่จะใช้ XSLT ซึ่งน่าเสียดาย! XSLT ที่เทียบเท่าสำหรับ JSON จะยอดเยี่ยม
Nicolas Le Thierry d'Ennequin

10
@ NicolasLeThierryd'Ennequin เห็นด้วย ผู้คนจำนวนมากเกลียดชัง XML ดังนั้นจึงเลิก XSLT เครื่องมือของระบบ XML นั้นมีความสำคัญอย่างยิ่งต่อผู้พัฒนา Java ซึ่งทำให้ผู้คนจำนวนมากขึ้น แต่ฉันเข้าสู่ XSLT อย่างหนักในช่วงกลางปี ​​2000 และมีพลังมหาศาลที่ไม่มีอะไรเทียบเท่าได้โดยตรงนอกระบบนิเวศ XML ฉันจะรัก JSON ที่เทียบเท่ากัน!
Zearin

คำตอบ:


77

ความคิดที่น่าสนใจ การค้นหาบางอย่างบน Google ให้ความสนใจเพียงไม่กี่หน้า ได้แก่ :

หวังว่านี่จะช่วยได้


10
ใช่ขอบคุณนั่นคือสิ่งที่ฉันกำลังมองหา น่าเสียดายที่เทคนิคไม่ได้รับความนิยมมากนัก JSON มักถูกใช้เป็นรูปแบบการส่งคืนในบริการสไตล์ REST และน่าจะมีวิธีมาตรฐานในการปรับใช้การแปลง
luvieere

8
รหัสนี้ใช้ string.eval () ... :-(
dreftymac

ลิงก์เฉพาะคำตอบ
Jean-François Fabre

102

XSLT ที่เทียบเท่าสำหรับ JSON - รายการของผู้สมัคร (เครื่องมือและข้อมูลจำเพาะ)

เครื่องมือ

  1. XSLT

    คุณสามารถใช้XSLT สำหรับ JSONกับจุดมุ่งหมายของFn: JSON เพื่อ XML

    ส่วนนี้อธิบายสิ่งอำนวยความสะดวกที่อนุญาตให้ประมวลผลข้อมูล JSON โดยใช้ XSLT

  2. JQ

    jq เปรียบเสมือน sed สำหรับข้อมูล JSON - คุณสามารถใช้มันเพื่อแบ่งและกรองและแม็พและแปลงข้อมูลที่มีโครงสร้างได้อย่างง่ายดายเช่น sed, awk, grep และเพื่อน ๆ ให้คุณเล่นกับข้อความ มีแพ็คเกจการติดตั้งสำหรับระบบปฏิบัติการที่แตกต่างกัน

  3. jj

    JJ เป็นยูทิลิตีบรรทัดคำสั่งที่ให้วิธีที่ง่ายและรวดเร็วในการดึงหรืออัปเดตค่าจากเอกสาร JSON มันขับเคลื่อนโดย GJSON และ SJSON ภายใต้ประทุน

  4. FX

    เครื่องมือประมวลผล JSON บรรทัดคำสั่ง

    • ไม่จำเป็นต้องเรียนรู้ไวยากรณ์ใหม่
    • JavaScript ธรรมดา
    • การจัดรูปแบบและการเน้น
    • ไบนารีแบบสแตนด์อโลน
  5. JL

    jl ("JSON lambda") เป็นภาษาทำงานขนาดเล็กสำหรับการสืบค้นและจัดการ JSON

  6. เขย่า

    ไลบรารีการแปลง JSON เป็น JSON ที่เขียนใน Java โดยที่ "ข้อมูลจำเพาะ" สำหรับการแปลงเป็นเอกสาร JSON

  7. Gron

    ทำให้ JSON ทำได้ง่ายขึ้น! gron แปลง JSON เป็นการกำหนดที่ไม่ต่อเนื่องเพื่อให้ grep ง่ายขึ้นสำหรับสิ่งที่คุณต้องการและดู 'เส้นทาง' ที่แน่นอน มันช่วยลดการสำรวจ API ที่คืนค่าจำนวนมากของ JSON แต่มีเอกสารประกอบที่แย่มาก

  8. JSON

    json เป็นเครื่องมือ CLI ที่รวดเร็วสำหรับการทำงานกับ JSON มันเป็นสคริปต์ไฟล์เดียว node.js ที่ไม่มี deps ภายนอก (นอกเหนือจาก 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 1 ธ.ค. 2017

    จัดเตรียมวิธีการจับคู่รูปแบบแบบเรียกซ้ำเพื่อเปลี่ยนข้อมูล JSON การแปลงรูปถูกกำหนดเป็นชุดของกฎที่ตรงกับโครงสร้างของวัตถุ JSON เมื่อการจับคู่เกิดขึ้นกฎจะปล่อยข้อมูลที่แปลงแล้วหรือเลือกที่จะเรียกซ้ำเพื่อเปลี่ยนวัตถุลูก

  13. jsawk Last commit 4 มี.ค. 2558

    Jsawk เหมือน awk แต่สำหรับ JSON คุณทำงานกับอาร์เรย์ของวัตถุ JSON ที่อ่านจาก stdin กรองโดยใช้ JavaScript เพื่อสร้างอาร์เรย์ผลลัพธ์ที่พิมพ์ไปยัง stdout

  14. yate Last Commit มี.ค. 13, 2017

    การทดสอบสามารถใช้เป็น docu https://github.com/pasaran/yate/tree/master/tests

  15. jsonpath-object-transform Last Commit 18 ม.ค. 2017

    ดึงข้อมูลจากวัตถุตามตัวอักษรโดยใช้ JSONPath และสร้างวัตถุใหม่ขึ้นอยู่กับแม่แบบ

  16. Stapling Last Commit 16 ก.ย. 2556

    Stapling เป็นไลบรารี JavaScript ที่เปิดใช้งานการจัดรูปแบบ XSLT สำหรับวัตถุ JSON แทนที่จะใช้เครื่องมือสร้างเทมเพลต JavaScript และเทมเพลตข้อความ / html การเย็บเล่มเปิดโอกาสให้คุณใช้เทมเพลต XSLT - โหลดแบบอะซิงโครนัสกับ Ajax และจากนั้นแคชฝั่งไคลเอ็นต์ - เพื่อวิเคราะห์แหล่งข้อมูล JSON ของคุณ

รายละเอียด:

  • JsonPointer

    JSON Pointer กำหนดไวยากรณ์สตริงสำหรับการระบุค่าเฉพาะภายในเอกสาร JavaScript Object Notation (JSON)

  • JsonPath

    นิพจน์ JSONPath มักอ้างถึงโครงสร้าง JSON ในลักษณะเดียวกับนิพจน์ XPath ที่ใช้ร่วมกับเอกสาร XML

  • JSPath

    JSPath สำหรับ JSON เหมือนกับ XPath สำหรับ XML "

  • JSONiq

    แหล่งที่มาหลักของแรงบันดาลใจที่อยู่เบื้องหลัง JSONiq คือ XQuery ซึ่งได้รับการพิสูจน์แล้วว่าเป็นภาษาคิวรีที่ประสบความสำเร็จและมีประสิทธิผลสำหรับข้อมูลแบบกึ่งโครงสร้าง


2
ขอบคุณสำหรับการโพสต์ที่มีประโยชน์มากและมีประโยชน์ เพื่อที่จะแปลง json หนึ่งบรรทัดเป็นรูปแบบที่อ่านได้ jq (nr.2 ในรายการของคุณ) เป็นทางเลือกที่ดีที่สุดสำหรับฉัน ขอบคุณอีกครั้ง!
นายกรัฐมนตรี

1
ฉันมักจะใช้json_ppสำหรับการพิมพ์ที่สวย มันมีให้สำหรับหลาย distros
jschnasse

70

ลองเขย่า เป็นไลบรารีการแปลง JSON ถึง JSON ที่เขียนด้วย Java

มันถูกสร้างขึ้นโดยเฉพาะเพราะเราไม่ต้องการเล่นเกม "JSON -> XML -> XSLT -> XML -> JSON" และการใช้เทมเพลตสำหรับการแปลงที่ซับซ้อนอย่างเพียงพอนั้นไม่สามารถทำได้


4
+9000: นี่เป็นโครงการที่จริงจัง! Huzzah การสาธิตออนไลน์พร้อมตัวอย่างช่วยยกระดับการเรียนรู้อย่างมาก: jolt-demo.appspot.com
kevinarpe

15

jq - ตัวประมวลผลบรรทัดคำสั่ง JSON แบบ Lightweight และยืดหยุ่น

มันไม่ใช่เทมเพลตอย่าง XSLT แต่มีความกระชับมากกว่า เช่นเพื่อแยกnameและaddressฟิลด์เป็นอาร์เรย์:[.name, .address]

กวดวิชาเดินผ่านตัวอย่างของการเปลี่ยนทวิตเตอร์ของ JSON API (การและคู่มือมีตัวอย่างมากมาย)


4
มันกระชับกว่าเพราะมันมีความสามารถน้อยกว่ามาก
Ihe Onwuka

ฉันไม่พบวิธีการค้นหาแอตทริบิวต์ที่กำหนดซ้ำ ๆ ในต้น Json
Daniel

@Daniel เป็น.. | .attr_name?สิ่งที่คุณกำลังมองหา? (จากstedolan.github.io/jq/manual/#RecursiveDescent: .. )
ankostis

1
อาจจะไม่เป็นที่มีความสามารถเป็น XSLT แต่มีประโยชน์มากและไม่เป็นความซับซ้อนเป็น XSLT
FLQ

15

XSLT รองรับ JSON ดังที่เห็นได้ที่http://www.w3.org/TR/xslt-30/#json

XML ใช้วงเล็บเหลี่ยมสำหรับโทเค็นตัวคั่น JSON ใช้เครื่องหมายวงเล็บวงเล็บเหลี่ยม ... I. e การเปรียบเทียบโทเค็นการรู้จำโทเค็นของ XML ที่น้อยลงหมายถึงมันถูกปรับให้เหมาะสำหรับการแปลงเชิงประกาศในขณะที่การเปรียบเทียบมากกว่านั้นก็เหมือนกับคำสั่งเปลี่ยนด้วยเหตุผลด้านความเร็ว เนื่องจากผลลัพธ์โดยตรงสำหรับการผสมผสานของข้อมูลกึ่งโครงสร้างที่แตกต่างกันคุณอาจต้องการเปรียบเทียบประสิทธิภาพของเครื่องมือ XSLT และ javascript เป็นส่วนหนึ่งของหน้าตอบสนอง สำหรับเพย์โหลดข้อมูลที่ไม่สามารถทำได้การแปลงอาจใช้ได้เช่นเดียวกับ JSON โดยไม่มีการทำให้เป็นอนุกรม XML การตัดสินใจของ W3 ควรอยู่บนพื้นฐานการวิเคราะห์ที่ดีขึ้น


15

ฉันเพิ่งพบเครื่องมือที่ฉันรักสำหรับจัดแต่งทรงผม JSON A: https://github.com/twigkit/tempo เครื่องมือที่ใช้งานง่ายมาก - ในความคิดของฉันมันง่ายกว่าที่จะทำงานกับ XSLT - ไม่จำเป็นต้องใช้คำสั่ง XPATH


9
Tempo ดูดีมากหากผลลัพธ์สุดท้ายของการแปลงเป็น HTML แต่ถ้าคุณต้องการจัดเรียงโครงสร้างโดยนัยให้เป็นโครงสร้างอื่น แต่ผลลัพธ์สุดท้ายยังคงเป็นJSON ฉันยังต้องการอะนาล็อกของ XPath เพื่อให้ฉันสามารถเขียนการแปลงในลักษณะที่ใช้งานได้
Toddius Zho

1
Tempo น่าสนใจมากขอบคุณจริงๆ อย่างไรก็ตามคุณสามารถส่ง xml ไปยังเบราว์เซอร์และ xslt (<? xsl-stylesheet>) และเบราว์เซอร์ของคุณจะใช้ xslt กับ xml โดยแสดงมุมมองที่กำหนดไว้ของ xml ของคุณโดยไม่ต้องใช้โค้ดใด ๆ เพิ่มเติม นี่ควรเป็นกรณีสำหรับ jsonT / tempo ด้วย
Martin Meeser


11

การบอกว่าการขาดเครื่องมือแนะนำการขาดความต้องการเป็นเพียงการขอร้องคำถาม เช่นเดียวกันสามารถนำไปใช้กับการสนับสนุน X หรือ Y ใน Linux (ทำไมต้องพัฒนาไดรเวอร์และ / หรือเกมที่มีคุณภาพสำหรับระบบปฏิบัติการส่วนน้อยเช่นนี้และทำไมต้องใส่ใจกับระบบปฏิบัติการที่ บริษัท เกมและฮาร์ดแวร์ขนาดใหญ่ไม่พัฒนา?) อาจเป็นคนที่จะต้องใช้ XSLT และ JSON ท้ายด้วยวิธีแก้ปัญหาเล็กน้อย: Transforming JSON เป็น XML แต่นั่นไม่ใช่ทางออกที่ดีที่สุดใช่ไหม

เมื่อคุณมีรูปแบบดั้งเดิมของ JSON และคุณต้องการแก้ไข "wysywyg" ในเบราว์เซอร์ XSLT จะเป็นทางออกที่เพียงพอสำหรับปัญหา การทำเช่นนั้นด้วยการเขียนโปรแกรมจาวาสคริปต์แบบดั้งเดิมอาจกลายเป็นความเจ็บปวดในตูด

ในความเป็นจริงฉันได้ใช้วิธี "ยุคหิน" กับ XSLT โดยใช้การแยกสตริงย่อยเพื่อตีความคำสั่งพื้นฐานบางอย่างสำหรับจาวาสคริปต์เช่นการเรียกแม่แบบกระบวนการลูก ๆ และอื่น ๆ แน่นอนว่าการใช้เครื่องมือการแปลงด้วยวัตถุ JSON นั้นง่ายกว่า การใช้งานตัวแยกวิเคราะห์ XML แบบเต็มรูปแบบเพื่อแยกวิเคราะห์ XSLT ปัญหาคือการใช้เทมเพลต XML เพื่อแปลงออบเจ็กต์ JSON คุณจะต้องแยกวิเคราะห์ XML ของเทมเพลต

ในการเปลี่ยนรูปแบบวัตถุ JSON ด้วย XML (หรือ HTML หรือข้อความหรืออะไรก็ตาม) คุณต้องคิดอย่างรอบคอบเกี่ยวกับไวยากรณ์และอักขระพิเศษที่คุณต้องใช้เพื่อระบุคำสั่งการแปลง ไม่เช่นนั้นคุณจะต้องออกแบบ parser สำหรับภาษาเทมเพลตของคุณเอง เมื่อเดินผ่านเส้นทางนั้นฉันสามารถบอกคุณได้ว่ามันไม่สวย

Update (12 พฤศจิกายน 2010): หลังจากสองสามสัปดาห์ทำงานกับ parser ของฉันฉันได้รับการเพิ่มประสิทธิภาพ เทมเพลตจะถูกวิเคราะห์คำล่วงหน้าและคำสั่งจะถูกเก็บเป็นวัตถุ JSON กฎการแปลงเป็นวัตถุ JSON ในขณะที่รหัสแม่แบบคือการผสมผสานของ HTML และไวยากรณ์โฮมบรูว์คล้ายกับรหัสเชลล์ ฉันสามารถแปลงเอกสาร JSON ที่ซับซ้อนเป็น HTML เพื่อสร้างเครื่องมือแก้ไขเอกสาร รหัสอยู่ที่ประมาณ 1K บรรทัดสำหรับโปรแกรมแก้ไข (สำหรับโครงการส่วนตัวดังนั้นฉันจึงไม่สามารถแชร์ได้) และประมาณ 990 บรรทัดสำหรับโค้ดการแปลง JSON (รวมคำสั่งการวนซ้ำการเปรียบเทียบอย่างง่ายการเรียกใช้เทมเพลตการบันทึกตัวแปรและการประเมินผล) ฉันวางแผนที่จะวางจำหน่ายภายใต้ใบอนุญาต MIT ส่งอีเมลหาฉันถ้าคุณต้องการมีส่วนร่วม


11

ฉันเขียนห้องสมุดเล็ก ๆ ของตัวเองเมื่อไม่นานมานี้ซึ่งพยายามอยู่ใกล้ ๆ

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

เป็นไปได้ (เท่าที่จะทำได้) ในโค้ด JavaScript สองสามบรรทัด

ต่อไปนี้เป็นตัวอย่างการใช้งานที่ไม่ยุ่งยากเล็กน้อย ...

1. JSON-to-some-markup:

ซอ: 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-to-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:

เทียบเท่า 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:

เทียบเท่า 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 นี้ (และอื่น ๆ แน่นอน)

เช่นวิธีรับส่วนลดของรายการขายของชำที่รู้รหัสแบรนด์ใน

{
 "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 , DSL สร้างแบบจำลองบน XPath และวิธีการจับคู่รูปแบบซ้ำ recursive แรงบันดาลใจโดยตรงจาก 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คุณสมบัติแล้วจับคู่ซ้ำ กฎข้อที่สองจับคู่วัตถุใด ๆ กับmakerคุณสมบัติส่งออกmodelและyearคุณสมบัติ สุดท้ายคือการแปลงรูปแบบที่ตรงกันซ้ำ


9

ในฐานะที่เป็นอีกหนึ่งคำตอบใหม่ที่จะเป็นคำถามที่เก่าผมขอแนะนำให้ดูที่DefiantJS มันไม่เทียบเท่า XSLT สำหรับ JSON แต่เป็น XSLT สำหรับ JSON ส่วน "Templating" ของเอกสารประกอบด้วยตัวอย่างนี้:

<!-- 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 เทมเพลตอินไลน์สไตล์มาร์กอัปที่แตกต่างกันทั้งหมดและตัดสินใจสร้างไลบรารีขนาดเล็กที่เปิดใช้งานการจัดรูปแบบ XSLT สำหรับโครงสร้างข้อมูล JSON ไม่ใช่วิทยาศาสตร์จรวด แต่อย่างใด - เป็นเพียง JSON ที่แยกวิเคราะห์ไปยัง XML แล้วจัดรูปแบบด้วยเอกสาร XSLT มันเร็วเกินไปไม่เร็วเท่าเอนจิ้นเทมเพลต JavaScript ใน Chrome แต่ในเบราว์เซอร์อื่น ๆ ส่วนใหญ่มันเร็วกว่าตัวเลือกเอ็นจิน JS สำหรับโครงสร้างข้อมูลที่ใหญ่กว่า


4

ฉันใช้ Camel route umarshal (xmljson) -> to (xlst) -> marshal (xmljson) มีประสิทธิภาพเพียงพอ (แม้ว่าจะไม่สมบูรณ์แบบ 100%) แต่ก็ง่ายถ้าคุณใช้ Camel อยู่แล้ว


3

JSONiqนั้นเป็นมาตรฐานและZorbaมีการใช้งาน C ++ แบบโอเพ่นซอร์ส JSONiq สามารถมองเห็นเป็น XQuery ด้วยการเพิ่ม JSON เป็นชนิดข้อมูลดั้งเดิม



2

Yate ( https://github.com/pasaran/yate ) ได้รับการออกแบบมาโดยเฉพาะหลังจาก XSLT มีคุณสมบัติ JPath (เทียบเท่า XPath ธรรมชาติสำหรับ JS) โดยรวมกับ JavaScript และมีประวัติการใช้งานจริงค่อนข้างมาก มันไม่มีเอกสารจริง แต่การอ่านตัวอย่างและการทดสอบควรจะเพียงพอ


2

JSLTนั้นใกล้กับ JSON ที่เทียบเท่ากับ XSLT มาก เป็นภาษาแปลงที่คุณเขียนส่วนคงที่ของเอาต์พุตในไวยากรณ์ 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
}

มันนำมาใช้ใน Java ด้านบนของแจ็คสัน


0

ไม่แน่ใจเกินไปว่ามีความต้องการสิ่งนี้และสำหรับฉันการขาดเครื่องมือชี้ให้เห็นถึงการขาดความต้องการ JSON ประมวลผลได้ดีที่สุดในฐานะวัตถุ (วิธีที่ทำใน JS ต่อไป) และโดยทั่วไปคุณใช้ภาษาของวัตถุเพื่อทำการแปลง (Java สำหรับวัตถุ Java ที่สร้างจาก JSON เช่นเดียวกับ Perl, Python, Perl, c #, PHP และอื่น ๆ บน). เพียงแค่มีการมอบหมายปกติ (หรือตั้งรับ) วนซ้ำและอื่น ๆ

ฉันหมายถึง XSLT เป็นเพียงอีกภาษาหนึ่งและเหตุผลหนึ่งที่จำเป็นคือ XML นั้นไม่ใช่สัญลักษณ์ของวัตถุและวัตถุของภาษาการเขียนโปรแกรมไม่ตรงตามความต้องการ (อิมพีแดนซ์ระหว่างโมเดล xml แบบลำดับชั้นและวัตถุ / โครงสร้าง)


หลังจากที่ Facebook แปลงจาก XML เป็น Json ฉันต้องมีเครื่องมืออย่างนี้
Joe Soul-bringer

คุณกำลังใช้กรณีอะไร จะสามารถแสดงเนื้อหา JSON คล้ายกับวิธีที่คุณแสดงการตอบสนอง XML เป็น HTML ได้หรือไม่ หรือสิ่งที่แตกต่างกันอย่างไร
StaxMan

ฉันสงสัยว่ามันจะง่ายเพียงใดในการจัดการการแปลง JSON วิธีวัตถุเชิงโปรแกรม (ด้วยการวนซ้ำการแตกแขนงตามต้องการ ฯลฯ ) เทียบกับวิธีการพิมพ์ XSLT โดยเฉพาะอย่างยิ่งในกรณีที่การแปลงวัตถุ JSON ขนาดใหญ่และข้อมูลบางอย่างในแหล่ง JSON ขึ้น / ลงบางโหนดในเป้าหมาย JSON (ไม่ใช่เพียงแค่สำเนาโดยตรงของโครงสร้าง) และบอกตำแหน่งที่โหนดใดโหนดหนึ่งในต้นทางหรือเป้าหมาย JSON เป็นส่วนหนึ่งของอาร์เรย์วัตถุภายใน JSON และ JSON อื่น (แหล่งที่มา / เป้าหมาย) ไม่ใช่ .
David

ความง่ายดายเป็นเรื่องส่วนตัวมากดังนั้นฉันสงสัยว่ามันเกี่ยวข้องกับสิ่งที่คุ้นเคย
StaxMan

ในขณะที่มีความต้องการการแปลง JSON แน่นอนคุณถูกต้องแล้วโดย JS :-) แต่คุณเคยเห็นjq - ตัวประมวลผลบรรทัดคำสั่ง JSON ที่เบาและยืดหยุ่นหรือไม่? โดยเฉพาะอย่างยิ่งเมื่อ JS ไม่พร้อมใช้งาน ฉันจะบอกว่าการเปลี่ยนแปลงนั้นง่ายกว่าและเป็นธรรมชาติมากกว่า JS เช่นเพื่อแยกฟิลด์nameและaddressและวางในอาร์เรย์:[.name, .address]
13ren

0

ทำไมคุณไม่แปลง JSON ให้เป็น XML โดยใช้Mr. Data Coverterลองเปลี่ยนมันด้วย XSLT แล้วเปลี่ยนกลับไปเป็น JSON ด้วยวิธีเดียวกัน


1
นี่ไม่ใช่ตัวเลือกถ้าคุณต้องการให้รหัสของคุณทำเพื่อคุณด้วยประสิทธิภาพที่ดี
orad

0

สำหรับดูเดิลที่ใช้งานได้ / การพิสูจน์แนวคิดเกี่ยวกับวิธีการใช้จาวาสคริปต์ที่บริสุทธิ์พร้อมกับรูปแบบที่คุ้นเคยและมีการประกาศหลัง XSLT ของนิพจน์ที่ตรงกันและแม่แบบเรียกซ้ำโปรดดูที่https://gist.github.com/brettz9/0e661b3093764f496e36

(อาจใช้วิธีที่คล้ายกันสำหรับ JSON)

โปรดทราบว่าการสาธิตอาศัยการปิด JavaScript 1.8 นิพจน์เพื่อความสะดวกในการแสดงเทมเพลตใน Firefox (อย่างน้อยก็จนกว่า ES6 แบบสั้นสำหรับวิธีการอาจนำไปใช้)

คำเตือน: นี่คือรหัสของฉันเอง


0

ฉันเขียนอะแดปเตอร์โดมสำหรับกรอบการประมวลผล json ตามแจ็คสันมานานแล้ว มันใช้ไลบรารี nu.xom ต้นไม้ dom ที่ได้นั้นทำงานได้กับสิ่งอำนวยความสะดวก java xpath และ xslt ฉันเลือกตัวเลือกการใช้งานที่ค่อนข้างตรงไปตรงมา ตัวอย่างเช่นรูทโหนดจะเรียกว่า "รูท" เสมออาร์เรย์จะเข้าสู่โหนด ol ที่มีองค์ประกอบย่อย li (เช่นใน html) และทุกอย่างอื่นเป็นเพียงโหนดย่อยที่มีค่าดั้งเดิมหรือโหนดวัตถุอื่น

JsonXmlConverter.java

การใช้งาน: JsonObject sampleJson = sampleJson(); org.w3c.dom.Document domNode = JsonXmlConverter.getW3cDocument(sampleJson, "root");


0

วิธีการหนึ่งที่ยังไม่ได้รับคือการใช้ตัวแยกวิเคราะห์เพื่อสร้างตัวแยกวิเคราะห์ใน XSLT ซึ่งแยกวิเคราะห์ JSON และสร้างเอาต์พุต XML

ตัวเลือกหนึ่งที่ได้รับการกล่าวถึงมากในการประชุม XML คือตัวสร้างตัวแยกวิเคราะห์ ReX ( http://www.bottlecaps.de/rex/ ) - แม้ว่าจะไม่มีเอกสารทั้งหมดในเว็บไซต์


0

อาจเป็นไปได้ที่จะใช้ XSLT กับ JSON Verson 3 ของ XPath (3.1) XSLT (3.0) และ XQuery (3.1) รองรับ JSON ในทางใดทางหนึ่ง ดูเหมือนว่าจะมีให้บริการในเวอร์ชันแซ็กซอนรุ่นโฆษณาและอาจรวมอยู่ในรุ่น 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.