使用存储在数组中的数据动态构建 JSON

Posted

技术标签:

【中文标题】使用存储在数组中的数据动态构建 JSON【英文标题】:Build a JSON dynamically with data stored in an array 【发布时间】:2019-02-28 19:47:32 【问题描述】:

我需要动态构建一个JSON

JSON 如果不是动态的,则可以工作。

这是一个工作示例,但 "@id""name" 不是动态的:

var el_2 = document.createElement('script');
el_2.type = 'application/ld+json';

el_2.text = JSON.stringify(
  "@context": "http://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    "@type": "ListItem",
    "position": 1,
    "item": 
      "@id": "https://example.com/",
      "name": "Home",
    
  , 
    "@type": "ListItem",
    "position": 2,
    "item": 
      "@id": "https://example.com/text_1",
      "name": "Text_1",
    
  , 
    "@type": "ListItem",
    "position": 3,
    "item": 
      "name": "Text_2",
    
  
  ]
);

document.querySelector('head').appendChild(el_2);

我需要让它动态化。

我使用jQuery’s each() 函数循环遍历面包屑的每个元素。

然后,我将元素压入数组:

var array_breadcrumb_text = [];
$('.region-breadcrumb .breadcrumb li').each(function(index, value) 
  array_breadcrumb_text.push($(this).find("a").attr('href') + ' : ' + $(this).text());
  // output of links and text is  correct
  console.log(array_breadcrumb_text[index]);
);

我不知道如何使用这个数组来构建 JSON。

通常,我使用foreach 循环,但由于我在JSON.stringify() 内,我不能使用foreach 循环,因为我有语法问题。

这是面包屑的 html 结构

<ol class="breadcrumb">
          <li>
                  <a href="/">Home</a>
          </li>
          <li>
                  <a href="/text_1">Text_1</a>
          </li>
          <li class="active">
                  Text_2
          </li>
 </ol>

【问题讨论】:

【参考方案1】:

我终于得到了足够的信息来意识到你可以做你想做的事。

所以我假设你想要这个:

var el_2 = document.createElement('script');
el_2.type = 'application/ld+json';
var bread = 
  "@context": "http://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": []


$('.breadcrumb li').each(function(index) 
  var item = 
  var href = $(this).find("a").attr('href');
  if (href) item["@id"] = href // OR location.protocol+"//"+location.host+href;
  item["name"] = $.trim($(this).text()); 

  bread.itemListElement.push(
    "@type": "ListItem",
    "position": index + 1,
    item
  )
);

el_2.text = JSON.stringify(bread);
console.log(JSON.stringify(bread,null,2))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ol class="breadcrumb">
  <li>
    <a href="/">Home</a>
  </li>
  <li>
    <a href="/text_1">Text_1</a>
  </li>
  <li class="active">
    Text_2
  </li>
</ol>

【讨论】:

我检查了&lt;script type="application/ld+json"&gt;&lt;/script&gt; 中的 JSON,它与我的问题中的示例完全匹配。这就是为什么我赞成并将您的答案标记为正确的原因。但它没有通过谷歌测试工具。如果我将您的代码输出的 JSON 代码复制粘贴到 &lt;head&gt; 并删除 JS,则它通过了 Google 测试工具。我花了几个小时在这上面,我现在不明白。我使用相同的原理为我的本地页面生成 JSON,在这种情况下它通过了 Google 测试工具。需要再次检查一切。找到解决方案后,我会尽快与您联系。 我现在唯一找到的东西,如果我在bread.itemListElement.push();中评论//item,我可以在谷歌测试工具中看到语言环境页面、徽标、面包屑、社交资料的所有结构化数据。当然,面包屑有错误(缺少项目),但谷歌找到了数据。 尝试更新 - 也许@ID 必须在名称之前 我已经尝试过了,但我会再试一次(需要仔细检查 ;-) 我在这个问题上花了几个小时,即使你的代码是正确的,它也没有通过结构化数据谷歌测试工具 (search.google.com/structured-data/testing-tool/u/0)。我现在的结论是我们不能使用object(您的代码中的item)。即使我在each() 之外使用item,并且如果我分配一个简单的值而不迭代DOM 元素,它也不起作用。它适用于我的本地页面,因为我只使用变量而不是object。需要找到替代方案,我猜是在服务器端创建它。【参考方案2】:

我会构建一个类似的函数:

function createListItem(el, index) 
    var $el = $(el);
    var data =  
        "@type": "ListItem",
        "position": index,
        "item": 
    ;

    data.item['@id'] = $el.find("a").attr('href');
    data.item.name = $el.text();
    // add image etc.

    return data;

这构建了数据结构的 ListItem 部分。你可以像这样构建它:

var array_breadcrumb_items = $('.region-breadcrumb .breadcrumb li').map(createListItem);

排序完成后,您可以:

var result = JSON.stringify(
  "@context": "http://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": array_breadcrumb_items
);

本质上,分解 JSON 结构的最简单方法是将其分解为可重复的部分,组装它们,然后尽可能晚地将结果传递给 JSON.stringify

【讨论】:

【参考方案3】:
<script>
    var bread = 
      "@context": "",
      "@type": "BreadcrumbList",
      "itemListElement": []
    
    $(document).ready(function () 
        var counter = 1;
        $('li[class*="breadcrumb-item"]').each(function(i,j)
         var href = $(this).find('a:first').attr('href');
         if (!href) href = location.href;
          bread.itemListElement.push(
            "@type": "ListItem",
            "position": counter,
            "item": href,
            "name": $.trim($(j).text())
          )
        counter++;
        );
        var jsonStr = JSON.stringify(bread);
        $('#dynamicJSONLD').append(jsonStr);
    );
</script>   
<script id="dynamicJSONLD" type="application/ld+json"></script>

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于使用存储在数组中的数据动态构建 JSON的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中动态构建 JSON

如何针对 JSON 列构建动态 SQL where 条件

使用 postgres 构建一个触发器函数来处理 json 数据

JavaScript:如何将数据添加到 JSON 文件中的数组

从 JSON 帐号数组构建 AWS IAM 策略

如何动态构建 JSON 对象?