吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 732|回复: 5
收起左侧

[其他原创] 基于html+jsonpath-plus库实现的jsonpath解析工具

[复制链接]
wxk0248 发表于 2025-7-6 01:10
今天,尝试了下让AI使用html+jsonpath-plus库实现jsonpath解析工具,要求可以离线使用。
结果并不理想,生成的代码无法直接运行,主要有两个问题:
1.deepseek非常执着于jsonpath-plus.min.js这个不存在的文件,查了下jsonpath-plus文档说明,可以使用https://github.com/JSONPath-Plus/JSONPath/blob/main/dist/index-browser-umd.cjs
2.AI调用相关方法时直接使用的是JSONPath({path: '...', json: {}}),结果一直跑不起来,报错JSONPath is not a function,让deepseek反复检查都无法修复,最后翻了下jsonpath-plus文档,正确的用法是:JSONPath.JSONPath({path: '...', json: {}});


成品截图
jsonpath解析工具.png

jsonpathtool.html源码
[HTML] 纯文本查看 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JsonPath解析工具</title>
    <script src="index-browser-umd.cjs"></script>
    <style>
      body {
        font-family: Arial, sans-serif;
        margin: 0;
        padding: 20px;
        display: flex;
        flex-direction: column;
        height: 100vh;
        box-sizing: border-box;
      }
      .container {
        display: flex;
        flex: 1;
        gap: 20px;
      }
      .panel {
        flex: 1;
        display: flex;
        flex-direction: column;
        min-width: 0;
      }
      .panel-header {
        font-weight: bold;
        margin-bottom: 10px;
        display: flex;
        justify-content: space-between;
        align-items: center;
      }
      .editor {
        flex: 1;
        border: 1px solid #ccc;
        border-radius: 4px;
        padding: 10px;
        font-family: monospace;
        overflow: auto;
        background-color: #f9f9f9;
        min-height: 0;
      }
      #jsonInput {
        width: 100%;
        height: calc(100% - 60px);
        resize: none;
        border: none;
        outline: none;
        background-color: transparent;
        font-family: monospace;
      }
      #resultOutput {
        white-space: pre-wrap;
        overflow: auto;
        height: 100%;
      }
      .jsonpath-input {
        margin-top: 10px;
        display: flex;
        gap: 10px;
      }
      #jsonpathInput {
        flex: 1;
        padding: 8px;
        border: 1px solid #ccc;
        border-radius: 4px;
      }
      button {
        padding: 8px 16px;
        background-color: #4caf50;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
        white-space: nowrap;
      }
      button:hover {
        background-color: #45a049;
      }
      .error {
        color: red;
        margin-top: 10px;
      }
      .examples {
        font-size: 0.9em;
        color: #666;
        margin-left: 35px;
        margin-top: 5px;
      }
      .example-btn {
        background: none;
        border: none;
        color: #06c;
        text-decoration: underline;
        cursor: pointer;
        padding: 0;
        margin: 0 5px;
        font-size: 0.9em;
      }
      .example-btn:hover {
        color: #004080;
      }
      .copy-btn {
        background-color: #f0f0f0;
        color: #333;
        padding: 2px 8px;
        font-size: 0.8em;
        border: 1px solid #ccc;
      }
      .copy-btn:hover {
        background-color: #e0e0e0;
      }
      .tabs {
        display: flex;
        margin-bottom: 10px;
      }
      .tab {
        padding: 8px 16px;
        cursor: pointer;
        border: 1px solid #ccc;
        border-bottom: none;
        border-radius: 4px 4px 0 0;
        background-color: #f0f0f0;
        margin-right: 5px;
      }
      .tab.active {
        background-color: #fff;
        border-bottom: 1px solid #fff;
        margin-bottom: -1px;
        z-index: 1;
      }
      .tab-content {
        display: none;
      }
      .tab-content.active {
        display: block;
      }
      /* Outer tabs styling */
      .outer-tabs {
        display: flex;
        margin-bottom: 10px;
      }
      .outer-tab {
        padding: 6px 20px;
        cursor: pointer;
        border: 1px solid #ccc;
        border-bottom: none;
        border-radius: 4px 4px 0 0;
        background-color: #f0f0f0;
        margin-right: 5px;
      }
      .outer-tab.active {
        background-color: #fff;
        border-bottom: 1px solid #fff;
        margin-bottom: -1px;
        z-index: 1;
      }
      .outer-tab-content {
        display: none;
        flex: 1;
        flex-direction: column;
      }
      .outer-tab-content.active {
        display: flex;
      }
      /* Reference table styling */
      table {
        width: 100%;
        border-collapse: collapse;
        margin-bottom: 20px;
      }
      th,
      td {
        border: 1px solid #ddd;
        padding: 8px;
        text-align: left;
      }
      th {
        background-color: #f2f2f2;
      }
      tr:nth-child(even) {
        background-color: #f9f9f9;
      }
      .reference-section {
        margin-bottom: 30px;
      }
      .reference-section h3 {
        border-bottom: 1px solid #eee;
        padding-bottom: 5px;
      }
      /* File upload button */
      .file-upload {
        position: relative;
        display: inline-block;
      }
      .file-upload input[type="file"] {
        position: absolute;
        left: 0;
        top: 0;
        opacity: 0;
        width: 100%;
        height: 100%;
        cursor: pointer;
      }
      .file-upload-btn {
        padding: 8px 10px;
        background-color: #2196f3;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
      }
      .file-upload-btn:hover {
        background-color: #0b7dda;
      }
      .panel-header-actions {
        display: flex;
        gap: 10px;
        align-items: center;
      }
    </style>
  </head>
  <body>
    <div class="outer-tabs">
      <div class="outer-tab active" data-outer-tab="tool">JsonPath解析工具</div>
      <div class="outer-tab" data-outer-tab="jsonpath-reference">
        JsonPath标准语法参考
      </div>
      <div class="outer-tab" data-outer-tab="jsonpath-plus-reference">
        JsonPath-Plus完整语法参考
      </div>
    </div>

    <div class="outer-tab-content active" id="tool-content">
      <div class="container">
        <div class="panel">
          <div class="panel-header">
            <div class="panel-header-actions">
              <div class="file-upload">
                <button class="file-upload-btn">上传JSON文件</button>
                <input type="file" id="jsonFileInput" accept=".json,application/json" />
              </div>
              <span>|   输入Json </span>
              <div class="examples">
                示例
                <button class="example-btn" data-example="basic">基本路径</button>
                <button class="example-btn" data-example="wildcard">
                  通配符
                </button>
                <button class="example-btn" data-example="filter">过滤器</button>
                <button class="example-btn" data-example="script">
                  脚本表达式
                </button>
              </div>
            </div>
              <button class="copy-btn" id="copyJsonBtn">复制</button>
          </div>
          <div class="editor">
            <textarea
              id="jsonInput"
              placeholder="请输入 Json 数据..."
            ></textarea>
          </div>
          <div class="jsonpath-input">
            <input
              type="text"
              id="jsonpathInput"
              placeholder="请输入 JSONPath 表达式,例如 $.store.book[*].author"
            />
            <button id="executeBtn">执行</button>
          </div>
          <div id="errorMsg" class="error"></div>
        </div>
        <div class="panel">
          <div class="panel-header">
            <span>解析结果</span>
            <button class="copy-btn" id="copyResultBtn">复制</button>
          </div>
          <div class="tabs">
            <div class="tab active" data-tab="result">结果</div>
            <div class="tab" data-tab="paths">路径</div>
            <div class="tab" data-tab="ast">AST</div>
          </div>
          <div class="editor">
            <div id="resultOutput" class="tab-content active"></div>
            <div id="pathsOutput" class="tab-content"></div>
            <div id="astOutput" class="tab-content"></div>
          </div>
        </div>
      </div>
    </div>

    <div class="outer-tab-content" id="jsonpath-reference-content">
      <div class="reference-section" style="overflow-y: auto; height: 100%;">
        <p>
          参考:
          <a href="https://goessner.net/articles/JsonPath/" target="_blank"
            >https://goessner.net/articles/JsonPath/</a
          >
        </p>

        <h3>JsonPath语法对照表</h3>
        <table>
          <tbody>
            <tr class="evn">
              <td><strong>XPath</strong></td>
              <td><strong>JsonPath</strong></td>
              <td><strong>Result</strong></td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>/store/book/author</code></td>
              <td class="lft"><code>$.store.book[*].author</code></td>
              <td class="lft">the authors of all books in the store</td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>//author</code></td>
              <td class="lft"><code>$..author</code></td>
              <td class="lft">all authors</td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>/store/*</code></td>
              <td class="lft"><code>$.store.*</code></td>
              <td class="lft">
                all things in store, which are some books and a red bicycle.
              </td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>/store//price</code></td>
              <td class="lft"><code>$.store..price</code></td>
              <td class="lft">the price of everything in the store.</td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>//book[3]</code></td>
              <td class="lft"><code>$..book[2]</code></td>
              <td class="lft">the third book</td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>//book[last()]</code></td>
              <td class="lft">
                <code>$..book[(@.length-1)]</code><br />
                <code>$..book[-1:]</code>
              </td>
              <td class="lft">the last book in order.</td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>//book[position()<3]</code></td>
              <td class="lft">
                <code>$..book[0,1]</code><br />
                <code>$..book[:2]</code>
              </td>
              <td class="lft">the first two books</td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>//book[isbn]</code></td>
              <td class="lft"><code>$..book[?(@.isbn)]</code></td>
              <td class="lft">filter all books with isbn number</td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>//book[price<10]</code></td>
              <td class="lft"><code>$..book[?(@.price<10)]</code></td>
              <td class="lft">filter all books cheapier than 10</td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>//*</code></td>
              <td class="lft"><code>$..*</code></td>
              <td class="lft">
                all Elements in XML document. All members of JSON structure.
              </td>
            </tr>
          </tbody>
        </table>

        <h3>JsonPath示例表</h3>
        <table>
          <tbody>
            <tr class="evn">
              <td><strong>XPath</strong></td>
              <td><strong>JSONPath</strong></td>
              <td><strong>Result</strong></td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>/store/book/author</code></td>
              <td class="lft"><code>$.store.book[*].author</code></td>
              <td class="lft">the authors of all books in the store</td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>//author</code></td>
              <td class="lft"><code>$..author</code></td>
              <td class="lft">all authors</td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>/store/*</code></td>
              <td class="lft"><code>$.store.*</code></td>
              <td class="lft">
                all things in store, which are some books and a red bicycle.
              </td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>/store//price</code></td>
              <td class="lft"><code>$.store..price</code></td>
              <td class="lft">the price of everything in the store.</td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>//book[3]</code></td>
              <td class="lft"><code>$..book[2]</code></td>
              <td class="lft">the third book</td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>//book[last()]</code></td>
              <td class="lft">
                <code>$..book[(@.length-1)]</code><br />
                <code>$..book[-1:]</code>
              </td>
              <td class="lft">the last book in order.</td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>//book[position()<3]</code></td>
              <td class="lft">
                <code>$..book[0,1]</code><br />
                <code>$..book[:2]</code>
              </td>
              <td class="lft">the first two books</td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>//book[isbn]</code></td>
              <td class="lft"><code>$..book[?(@.isbn)]</code></td>
              <td class="lft">filter all books with isbn number</td>
            </tr>
            <tr class="odd">
              <td class="lft"><code>//book[price<10]</code></td>
              <td class="lft"><code>$..book[?(@.price<10)]</code></td>
              <td class="lft">filter all books cheapier than 10</td>
            </tr>
            <tr class="evn">
              <td class="lft"><code>//*</code></td>
              <td class="lft"><code>$..*</code></td>
              <td class="lft">
                all Elements in XML document. All members of JSON structure.
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

    <div class="outer-tab-content" id="jsonpath-plus-reference-content">
      <div class="reference-section" style="overflow-y: auto; height: 100%;">
        <p>
          参考:
          <a
            href="https://github.com/JSONPath-Plus/JSONPath?tab=readme-ov-file"
            target="_blank"
            >https://github.com/JSONPath-Plus/JSONPath</a
          >
        </p>

        <h3>JsonPath-Plus 扩展语法</h3>
        <table>
          <thead>
            <tr>
              <th>XPath</th>
              <th>JsonPath</th>
              <th>Result</th>
              <th>Notes</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td><code>/store/book/author</code></td>
              <td><code>$.store.book[*].author</code></td>
              <td>The authors of all books in the store</td>
              <td>
                Can also be represented without the <code>$.</code> as
                <code>store.book[*].author</code> (though this is not present in
                the original spec); note that some character literals (<code
                  >$</code
                >
                and <code>@</code>) require escaping, however
              </td>
            </tr>
            <tr>
              <td><code>//author</code></td>
              <td><code>$..author</code></td>
              <td>All authors</td>
              <td></td>
            </tr>
            <tr>
              <td><code>/store/*</code></td>
              <td><code>$.store.*</code></td>
              <td>
                All things in store, which are its books (a book array) and a
                red bicycle (a bicycle object).
              </td>
              <td></td>
            </tr>
            <tr>
              <td><code>/store//price</code></td>
              <td><code>$.store..price</code></td>
              <td>The price of everything in the store.</td>
              <td></td>
            </tr>
            <tr>
              <td><code>//book[3]</code></td>
              <td><code>$..book[2]</code></td>
              <td>The third book (book object)</td>
              <td></td>
            </tr>
            <tr>
              <td><code>//book[last()]</code></td>
              <td>
                <code>$..book[(@.length-1)]</code> <br />
                <code>$..book[-1:]</code>
              </td>
              <td>The last book in order.</td>
              <td>
                To access a property with a special character, utilize
                <code>[(@['...'])]</code> for the filter (this particular
                feature is not present in the original spec)
              </td>
            </tr>
            <tr>
              <td><code>//book[position()<3]</code></td>
              <td>
                <code>$..book[0,1]</code> <br />
                <code>$..book[:2]</code>
              </td>
              <td>The first two books</td>
              <td></td>
            </tr>
            <tr>
              <td>
                <code>//book/*[self::category|self::author]</code> or
                <code>//book/(category,author)</code> in XPath 2.0
              </td>
              <td><code>$..book[0][category,author]</code></td>
              <td>The categories and authors of all books</td>
              <td></td>
            </tr>
            <tr>
              <td><code>//book[isbn]</code></td>
              <td><code>$..book[?(@.isbn)]</code></td>
              <td>Filter all books with an ISBN number</td>
              <td>
                To access a property with a special character, utilize
                <code>[?@['...']]</code> for the filter (this particular feature
                is not present in the original spec)
              </td>
            </tr>
            <tr>
              <td><code>//book[price<10]</code></td>
              <td><code>$..book[?(@.price<10)]</code></td>
              <td>Filter all books cheaper than 10</td>
              <td></td>
            </tr>
            <tr>
              <td><code>//*[name() = 'price' and . != 8.95]</code></td>
              <td>
                <code
                  >$..*[?(@property === 'price' && @ !== 8.95)]</code
                >
              </td>
              <td>
                Obtain all property values of objects whose property is price
                and which does not equal 8.95
              </td>
              <td>
                With the bare <code>@</code> allowing filtering objects by
                property value (not necessarily within arrays), you can add
                <code>^</code> after the expression to get at the object
                possessing the filtered properties
              </td>
            </tr>
            <tr>
              <td><code>/</code></td>
              <td><code>$</code></td>
              <td>
                The root of the JSON object (i.e., the whole object itself)
              </td>
              <td>
                To get a literal <code>$</code> (by itself or anywhere in the
                path), you must use the backtick escape
              </td>
            </tr>
            <tr>
              <td><code>//*/*|//*/*/text()</code></td>
              <td><code>$..*</code></td>
              <td>
                All Elements (and text) beneath root in an XML document. All
                members of a JSON structure beneath the root.
              </td>
              <td></td>
            </tr>
            <tr>
              <td><code>//*</code></td>
              <td><code>$..</code></td>
              <td>
                All Elements in an XML document. All parent components of a JSON
                structure including root.
              </td>
              <td>
                This behavior was not directly specified in the original spec
              </td>
            </tr>
            <tr>
              <td><code>//*[price>19]/..</code></td>
              <td><code>$..[?(@.price>19)]^</code></td>
              <td>
                Parent of those specific items with a price greater than 19
                (i.e., the store value as the parent of the bicycle and the book
                array as parent of an individual book)
              </td>
              <td>Parent (caret) not present in the original spec</td>
            </tr>
            <tr>
              <td><code>/store/*/name()</code> (in XPath 2.0)</td>
              <td><code>$.store.*~</code></td>
              <td>
                The property names of the store sub-object ("book" and
                "bicycle"). Useful with wildcard properties.
              </td>
              <td>Property name (tilde) is not present in the original spec</td>
            </tr>
            <tr>
              <td>
                <code>/store/book[not(. is /store/book[1])]</code> (in XPath
                2.0)
              </td>
              <td>
                <code>$.store.book[?(@path !== "$['store']['book'][0]")]</code>
              </td>
              <td>All books besides that at the path pointing to the first</td>
              <td><code>@path</code> is not present in the original spec</td>
            </tr>
            <tr>
              <td>
                <code>//book[parent::*/bicycle/color = "red"]/category</code>
              </td>
              <td>
                <code
                  >$..book[?(@parent.bicycle && @parent.bicycle.color
                  === "red")].category</code
                >
              </td>
              <td>
                Grabs all categories of books where the parent object of the
                book has a bicycle child whose color is red (i.e., all the
                books)
              </td>
              <td><code>@parent</code> is not present in the original spec</td>
            </tr>
            <tr>
              <td><code>//book/*[name() != 'category']</code></td>
              <td><code>$..book.*[?(@property !== "category")]</code></td>
              <td>Grabs all children of "book" except for "category" ones</td>
              <td>
                <code>@property</code> is not present in the original spec
              </td>
            </tr>
            <tr>
              <td><code>//book[position() != 1]</code></td>
              <td><code>$..book[?(@property !== 0)]</code></td>
              <td>
                Grabs all books whose property (which, being that we are
                reaching inside an array, is the numeric index) is not 0
              </td>
              <td>
                <code>@property</code> is not present in the original spec
              </td>
            </tr>
            <tr>
              <td><code>/store/*/*[name(parent::*) != 'book']</code></td>
              <td><code>$.store.*[?(@parentProperty !== "book")]</code></td>
              <td>
                Grabs the grandchildren of store whose parent property is not
                book (i.e., bicycle's children, "color" and "price")
              </td>
              <td>
                <code>@parentProperty</code> is not present in the original spec
              </td>
            </tr>
            <tr>
              <td>
                <code>//book[count(preceding-sibling::*) != 0]/*/text()</code>
              </td>
              <td><code>$..book.*[?(@parentProperty !== 0)]</code></td>
              <td>
                Get the property values of all book instances whereby the parent
                property of these values (i.e., the array index holding the book
                item parent object) is not 0
              </td>
              <td>
                <code>@parentProperty</code> is not present in the original spec
              </td>
            </tr>
            <tr>
              <td><code>//book[price = /store/book[3]/price]</code></td>
              <td>
                <code>$..book[?(@.price === @root.store.book[2].price)]</code>
              </td>
              <td>
                Filter all books whose price equals the price of the third book
              </td>
              <td><code>@root</code> is not present in the original spec</td>
            </tr>
            <tr>
              <td>
                <code>//book/../*[. instance of element(*, xs:decimal)]</code>
                (in XPath 2.0)
              </td>
              <td><code>$..book..*@number()</code></td>
              <td>Get the numeric values within the book array</td>
              <td>
                <code>@number()</code>, the other basic types
                (<code>@boolean()</code>, <code>@string()</code>), other
                low-level derived types (<code>@null()</code>,
                <code>@object()</code>, <code>@array()</code>), the
                JSONSchema-added type, <code>@integer()</code>, the compound
                type <code>@scalar()</code> (which also accepts
                <code>undefined</code> and non-finite numbers for JavaScript
                objects as well as all of the basic non-object/non-function
                types), the type, <code>@other()</code>, to be used in
                conjunction with a user-defined callback (see
                <code>otherTypeCallback</code>) and the following non-JSON types
                that can nevertheless be used with JSONPath when querying
                non-JSON JavaScript objects (<code>@undefined()</code>,
                <code>@function()</code>, <code>@nonFinite()</code>) are not
                present in the original spec
              </td>
            </tr>
            <tr>
              <td>
                <code
                  >//book/*[name() = 'category' and matches(., 'tion$')]</code
                >
                (XPath 2.0)
              </td>
              <td>
                <code
                  >$..book.*[?(@property === "category" &&
                  @.match(/TION$/i))]</code
                >
              </td>
              <td>
                All categories of books which match the regex (end in 'TION'
                case insensitive)
              </td>
              <td>
                <code>@property</code> is not present in the original spec.
              </td>
            </tr>
            <tr>
              <td>
                <code>//book/*[matches(name(), 'bn$')]/parent::*</code> (XPath
                2.0)
              </td>
              <td><code>$..book.*[?(@property.match(/bn$/i))]^</code></td>
              <td>
                All books which have a property matching the regex (end in
                'TION' case insensitive)
              </td>
              <td>
                <code>@property</code> is not present in the original spec.
                Note: Uses the parent selector <code>^</code> at the end of the
                expression to return to the parent object; without the parent
                selector, it matches the two <code>isbn</code> key values.
              </td>
            </tr>
            <tr>
              <td></td>
              <td>
                <code>`</code> (e.g., <code> `$</code> to match a property
                literally named <code>$</code>)
              </td>
              <td>
                Escapes the entire sequence following (to be treated as a
                literal)
              </td>
              <td>
                <code>`</code> is not present in the original spec; to get a
                literal backtick, use an additional backtick to escape
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

    <script>
      document.addEventListener('DOMContentLoaded', function () {
        const jsonInput = document.getElementById('jsonInput')
        const jsonpathInput = document.getElementById('jsonpathInput')
        const executeBtn = document.getElementById('executeBtn')
        const resultOutput = document.getElementById('resultOutput')
        const pathsOutput = document.getElementById('pathsOutput')
        const astOutput = document.getElementById('astOutput')
        const errorMsg = document.getElementById('errorMsg')
        const copyJsonBtn = document.getElementById('copyJsonBtn')
        const copyResultBtn = document.getElementById('copyResultBtn')
        const exampleBtns = document.querySelectorAll('.example-btn')
        const tabs = document.querySelectorAll('.tab')
        const outerTabs = document.querySelectorAll('.outer-tab')
        const jsonFileInput = document.getElementById('jsonFileInput')

        // 设置默认JSON示例
        const defaultJson = {
          store: {
            book: [
              {
                category: 'reference',
                author: 'Nigel Rees',
                title: 'Sayings of the Century',
                price: 8.95,
                inStock: true,
              },
              {
                category: 'fiction',
                author: 'Evelyn Waugh',
                title: 'Sword of Honour',
                price: 12.99,
                inStock: false,
              },
              {
                category: 'fiction',
                author: 'Herman Melville',
                title: 'Moby Dick',
                isbn: '0-553-21311-3',
                price: 8.99,
                inStock: true,
              },
              {
                category: 'fiction',
                author: 'J. R. R. Tolkien',
                title: 'The Lord of the Rings',
                isbn: '0-395-19395-8',
                price: 22.99,
                inStock: false,
              },
            ],
            bicycle: {
              color: 'red',
              price: 19.95,
              inStock: true,
            },
            meta: {
              created: '2023-01-01',
              updated: '2023-06-15',
            },
          },
          authors: [
            'Nigel Rees',
            'Evelyn Waugh',
            'Herman Melville',
            'J. R. R. Tolkien',
          ],
          timestamp: 1687046400,
        }

        jsonInput.value = JSON.stringify(defaultJson, null, 2)

        // 设置默认JSONPath示例
        jsonpathInput.value = '$.store.book[0].author'

        // 示例数据
        const examples = {
          basic: {
            path: '$.store.book[0].author',
            desc: '获取第一本书的作者',
          },
          wildcard: {
            path: '$..author',
            desc: '递归查找所有author字段',
          },
          filter: {
            path: '$.store.book[?(@.price < 10)]',
            desc: '查找价格低于10的书',
          },
          script: {
            path: '$.store.book[?(@.price > @root.store.bicycle.price)]',
            desc: '查找价格高于自行车的书',
          },
        }

        // 事件监听
        executeBtn.addEventListener('click', executeJsonPath)
        jsonpathInput.addEventListener('keyup', function (e) {
          if (e.key === 'Enter') {
            executeJsonPath()
          }
        })

        copyJsonBtn.addEventListener('click', function () {
          navigator.clipboard
            .writeText(jsonInput.value)
            .then(() => console.log('JSON已复制到剪贴板'))
            .catch((err) => console.error('复制失败:', err))
        })

        copyResultBtn.addEventListener('click', function () {
          const activeTab = document.querySelector('.tab.active')
          let textToCopy = ''

          if (activeTab.dataset.tab === 'result') {
            textToCopy = resultOutput.textContent
          } else if (activeTab.dataset.tab === 'paths') {
            textToCopy = pathsOutput.textContent
          } else if (activeTab.dataset.tab === 'ast') {
            textToCopy = astOutput.textContent
          }

          navigator.clipboard
            .writeText(textToCopy)
            .then(() => console.log('内容已复制到剪贴板'))
            .catch((err) => console.error('复制失败:', err))
        })

        exampleBtns.forEach((btn) => {
          btn.addEventListener('click', function () {
            const example = examples[this.dataset.example]
            jsonpathInput.value = example.path
            executeJsonPath()
          })
        })

        tabs.forEach((tab) => {
          tab.addEventListener('click', function () {
            tabs.forEach((t) => t.classList.remove('active'))
            this.classList.add('active')

            document.querySelectorAll('.tab-content').forEach((content) => {
              content.classList.remove('active')
            })

            document
              .getElementById(`${this.dataset.tab}Output`)
              .classList.add('active')
          })
        })

        outerTabs.forEach((tab) => {
          tab.addEventListener('click', function () {
            outerTabs.forEach((t) => t.classList.remove('active'))
            this.classList.add('active')

            document
              .querySelectorAll('.outer-tab-content')
              .forEach((content) => {
                content.classList.remove('active')
              })

            document
              .getElementById(`${this.dataset.outerTab}-content`)
              .classList.add('active')
          })
        })

        // 添加文件上传处理
        jsonFileInput.addEventListener('change', function (e) {
          const file = e.target.files[0]
          if (!file) return

          const reader = new FileReader()
          reader.onload = function (e) {
            try {
              const content = e.target.result
              // 尝试解析JSON以验证格式
              const jsonData = JSON.parse(content)
              // 如果解析成功,设置到文本区域
              jsonInput.value = JSON.stringify(jsonData, null, 2)
              errorMsg.textContent = ''
            } catch (error) {
              errorMsg.textContent = '错误: 文件内容不是有效的JSON - ' + error.message
            }
          }
          reader.onerror = function () {
            errorMsg.textContent = '错误: 读取文件失败'
          }
          reader.readAsText(file)
        })

        function executeJsonPath() {
          errorMsg.textContent = ''
          resultOutput.textContent = ''
          pathsOutput.textContent = ''
          astOutput.textContent = ''

          try {
            const jsonData = JSON.parse(jsonInput.value)
            const jsonPathExpr = jsonpathInput.value.trim()

            if (!jsonPathExpr) {
              throw new Error('请输入 JSONPath 表达式')
            }

            // 执行JSONPath查询
            const result = JSONPath.JSONPath({
              path: jsonPathExpr,
              json: jsonData,
              resultType: 'value',
              flatten: true,
            })

            // 获取路径信息
            const paths = JSONPath.JSONPath({
              path: jsonPathExpr,
              json: jsonData,
              resultType: 'path',
            })

            // 获取AST信息
            const ast = JSONPath.JSONPath({
              path: jsonPathExpr,
              json: jsonData,
              resultType: 'pointer',
              preventEval: true,
            })

            // 显示结果
            if (result === undefined || result.length === 0) {
              resultOutput.textContent = '没有匹配的结果'
            } else {
              resultOutput.textContent = JSON.stringify(result, null, 2)
              pathsOutput.textContent = paths.join('\n')
              astOutput.textContent = JSON.stringify(ast, null, 2)
            }
          } catch (error) {
            errorMsg.textContent = '错误: ' + error.message
            console.error(error)
          }
        }

        // 初始执行
        executeJsonPath()
      })
    </script>
  </body>
</html>


index-browser-umd.cjs可以去git仓库自行下载:https://github.com/JSONPath-Plus/JSONPath/blob/main/dist/index-browser-umd.cjs




懒人链接:https://pan.baidu.com/s/1Qwt5oWwExQrtGQU-1hcl1g?pwd=52pj



免费评分

参与人数 3吾爱币 +8 热心值 +3 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xlln + 1 + 1 我很赞同!
shengruqing + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

samly1029 发表于 2025-7-6 01:13
运行结果出错,能否修改?
 楼主| wxk0248 发表于 2025-7-6 01:25
samly1029 发表于 2025-7-6 01:13
运行结果出错,能否修改?

已验证环境:Google浏览器- 64位-版本138.0.7204.97
samly1029 发表于 2025-7-6 01:26
wxk0248 发表于 2025-7-6 01:25
已验证环境:Google浏览器- 64位-版本138.0.7204.97

没错就是你说的浏览器
ysjd22 发表于 2025-7-6 08:48
这几天再发愁这个呢。谢谢
zhangsan2022 发表于 2025-7-6 09:12
多谢分享,不错。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-7-20 20:08

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表