如何使用 PHP 将 HTML 转换为 JSON?

2023-11-23

我可以使用将 JSON 转换为 HTMLJsontoHtml图书馆。现在,我需要将当前的 HTML 转换为 JSON,如本网站所示。当查看代码时,我发现以下脚本:

<script>
$(function(){

    //HTML to JSON
    $('#btn-render-json').click(function() {

        //Set html output
        $('#html-output').html( $('#html-input').val() );

        //Process to JSON and format it for consumption
        $('#html-json').html( FormatJSON(toTransform($('#html-output').children())) );
    });

});

//Convert obj or array to transform
function toTransform(obj) {

    var json;

    if( obj.length > 1 )
    {
        json = [];

        for(var i = 0; i < obj.length; i++)
            json[json.length++] = ObjToTransform(obj[i]);
    } else
        json = ObjToTransform(obj);

    return(json);
}

//Convert obj to transform
function ObjToTransform(obj)
{
    //Get the DOM element
    var el = $(obj).get(0);

    //Add the tag element
    var json = {'tag':el.nodeName.toLowerCase()};

    for (var attr, i=0, attrs=el.attributes, l=attrs.length; i<l; i++){
        attr = attrs[i];
        json[attr.nodeName] = attr.value;
    }

    var children = $(obj).children();

    if( children.length > 0 ) json['children'] = [];
    else json['html'] = $(obj).text();

    //Add the children
    for(var c = 0; c < children.length; c++)
        json['children'][json['children'].length++] = toTransform(children[c]);

    return(json);
}

//Format JSON (with indents)
function FormatJSON(oData, sIndent) {
    if (arguments.length < 2) {
        var sIndent = "";
    }
    var sIndentStyle = "  ";
    var sDataType = RealTypeOf(oData);

    // open object
    if (sDataType == "array") {
        if (oData.length == 0) {
            return "[]";
        }
        var sHTML = "[";
    } else {
        var iCount = 0;
        $.each(oData, function() {
            iCount++;
            return;
        });
        if (iCount == 0) { // object is empty
            return "{}";
        }
        var sHTML = "{";
    }

    // loop through items
    var iCount = 0;
    $.each(oData, function(sKey, vValue) {
        if (iCount > 0) {
            sHTML += ",";
        }
        if (sDataType == "array") {
            sHTML += ("\n" + sIndent + sIndentStyle);
        } else {
            sHTML += ("\"" + sKey + "\"" + ":");
        }

        // display relevant data type
        switch (RealTypeOf(vValue)) {
            case "array":
            case "object":
                sHTML += FormatJSON(vValue, (sIndent + sIndentStyle));
                break;
            case "boolean":
            case "number":
                sHTML += vValue.toString();
                break;
            case "null":
                sHTML += "null";
                break;
            case "string":
                sHTML += ("\"" + vValue + "\"");
                break;
            default:
                sHTML += ("TYPEOF: " + typeof(vValue));
        }

        // loop
        iCount++;
    });

    // close object
    if (sDataType == "array") {
        sHTML += ("\n" + sIndent + "]");
    } else {
        sHTML += ("}");
    }

    // return
    return sHTML;
}

//Get the type of the obj (can replace by jquery type)
function RealTypeOf(v) {
  if (typeof(v) == "object") {
    if (v === null) return "null";
    if (v.constructor == (new Array).constructor) return "array";
    if (v.constructor == (new Date).constructor) return "date";
    if (v.constructor == (new RegExp).constructor) return "regex";
    return "object";
  }
  return typeof(v);
}
</script>

enter image description here

现在,我需要在 PHP 中使用以下函数。我可以获取 HTML 数据。我现在需要的就是将 JavaScript 函数转换为 PHP 函数。这可能吗?我的主要疑惑有以下几点:

  • Javascript 函数的主要输入toTransform()是一个对象。是否可以通过 PHP 将 HTML 转换为对象?

  • 这个特定 JavaScript 中存在的所有函数都可以在 PHP 中使用吗?

请给我建议这个想法。

When I tried to convert script tag to json as per the answer given, I get errors. When I tried it in json2html site, it showed like this:enter image description here .. How to achieve the same solution?


如果您能够获得DOMDocument代表你的 HTML 的对象,那么你只需要递归地遍历它并构建你想要的数据结构。

将您的 HTML 文档转换为DOMDocument应该像这样简单:

function html_to_obj($html) {
    $dom = new DOMDocument();
    $dom->loadHTML($html);
    return element_to_obj($dom->documentElement);
}

然后简单遍历一下$dom->documentElement这给出了您所描述的结构可能如下所示:

function element_to_obj($element) {
    $obj = array( "tag" => $element->tagName );
    foreach ($element->attributes as $attribute) {
        $obj[$attribute->name] = $attribute->value;
    }
    foreach ($element->childNodes as $subElement) {
        if ($subElement->nodeType == XML_TEXT_NODE) {
            $obj["html"] = $subElement->wholeText;
        }
        else {
            $obj["children"][] = element_to_obj($subElement);
        }
    }
    return $obj;
}

测试用例

$html = <<<EOF
<!DOCTYPE html>
<html lang="en">
    <head>
        <title> This is a test </title>
    </head>
    <body>
        <h1> Is this working? </h1>  
        <ul>
            <li> Yes </li>
            <li> No </li>
        </ul>
    </body>
</html>

EOF;

header("Content-Type: text/plain");
echo json_encode(html_to_obj($html), JSON_PRETTY_PRINT);

Output

{
    "tag": "html",
    "lang": "en",
    "children": [
        {
            "tag": "head",
            "children": [
                {
                    "tag": "title",
                    "html": " This is a test "
                }
            ]
        },
        {
            "tag": "body",
            "html": "  \n        ",
            "children": [
                {
                    "tag": "h1",
                    "html": " Is this working? "
                },
                {
                    "tag": "ul",
                    "children": [
                        {
                            "tag": "li",
                            "html": " Yes "
                        },
                        {
                            "tag": "li",
                            "html": " No "
                        }
                    ],
                    "html": "\n        "
                }
            ]
        }
    ]
}

回答更新的问题

上面提出的解决方案不适用于<script>元素,因为它不被解析为DOMText,但作为DOMCharacterData目的。这是因为 PHP 中的 DOM 扩展是基于libxml2,它将您的 HTML 解析为 HTML 4.0,并且在 HTML 4.0 中,内容为<script>属于类型CDATA并不是#PCDATA.

对于这个问题你有两种解决方案。

  1. 简单但不是很稳健的解决方案是添加LIBXML_NOCDATA标记为DOMDocument::loadHTML.(我实际上并不能 100% 确定这是否适用于 HTML 解析器。)

  2. 更困难但在我看来更好的解决方案是在测试时添加额外的测试$subElement->nodeType在递归之前。递归函数将变为:

function element_to_obj($element) {
    echo $element->tagName, "\n";
    $obj = array( "tag" => $element->tagName );
    foreach ($element->attributes as $attribute) {
        $obj[$attribute->name] = $attribute->value;
    }
    foreach ($element->childNodes as $subElement) {
        if ($subElement->nodeType == XML_TEXT_NODE) {
            $obj["html"] = $subElement->wholeText;
        }
        elseif ($subElement->nodeType == XML_CDATA_SECTION_NODE) {
            $obj["html"] = $subElement->data;
        }
        else {
            $obj["children"][] = element_to_obj($subElement);
        }
    }
    return $obj;
}

如果您遇到此类错误,您应该做的第一件事就是检查节点的类型$subElement是,因为存在许多其他可能性我的简短示例函数没有处理。

此外,您会注意到libxml2必须修复 HTML 中的错误才能为其构建 DOM。这就是为什么一个<html> and a <head>即使您没有指定元素,它们也会出现。您可以通过使用来避免这种情况LIBXML_HTML_NOIMPLIED flag.

带脚本的测试用例

$html = <<<EOF
        <script type="text/javascript">
            alert('hi');
        </script>
EOF;

header("Content-Type: text/plain");
echo json_encode(html_to_obj($html), JSON_PRETTY_PRINT);

Output

{
    "tag": "html",
    "children": [
        {
            "tag": "head",
            "children": [
                {
                    "tag": "script",
                    "type": "text\/javascript",
                    "html": "\n            alert('hi');\n        "
                }
            ]
        }
    ]
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 PHP 将 HTML 转换为 JSON? 的相关文章

  • Angular 4 Http POST 不起作用

    我希望每个人都做得很好 我最近开始使用 Angular 4 4 我一直在尝试将数据发布到我的 api 服务器 但不幸的是它不起作用 我花了大约两天的时间 但仍然没有成功 甚至已经尝试过 6 7 篇文章角 io https angular i
  • Chrome --app 相当于 Firefox\IE

    我有一个网络应用程序 客户要求单击不同按钮时更改浏览器窗口大小 我发现在那link https stackoverflow com questions 13436855 launch google chrome from the comma
  • 播放没有音频标签的音频

    是否可以在没有音频标签的情况下仅使用 javascript 播放音频 我通过 tinyMce 编辑器注入脚本 因为我无权访问网站的后端 并且它不支持客户端的音频标签 她只想要当您将鼠标悬停在图像上时发出简单的声音 我已经完成了所有设置 但是
  • 如何使用 PHP 将字符串按大写字母分解?

    我有一个字符串 CamelCaseString 我想对大写字母进行explode split 或一些更好的方法来将该字符串分解为单个单词 最简单的方法是什么 解决方案更新 此链接指向一个略有不同的问题 但我认为答案通常比本页当前问题的答案更
  • ES6 模块范围

    我有代码 lib js var a a export var b b main js console log a a variable is not available in a global scope import b from lib
  • 从字节数组设置 img src

    我需要设置img src我在对象中拥有的字节数组的属性 img
  • 后退按钮 (Chrome) 在 Play Framework 中获取 Json 而不是 HTML

    各位 我有一个 Web 应用程序 我在其中对同一资源的 JSON 和 HTML 表示重复使用了相同的路由 现在我们将其称为 foo details 该页面是从 bar details 链接的 因此 查看 bar details 您会看到链接
  • Svelte 条件元素类报告为语法错误

    我正在做一个if块每if 块的精简指南 https svelte technology guide if blocks 这看起来很简单 但 Svelte 认为这是一个语法错误 svelte plugin ParseError Unexpec
  • 在反应中访问回调内的 event.target

    我有以下课程片段 constructor props super props this timeout null search e gt clearTimeout this timeout this timeout setTimeout f
  • 禁用复选框上的输入

    需要在取消选中该复选框时禁用输入 并在选中该复选框时启用它 我的代码是这样的 div class y div
  • WordPress 子主题包括包含文件

    我在一家WordPress使用 AMPPS 作为本地主机在我的本地计算机上进行设置 使用 Delta 主题 我创建了一个子主题 delta2 child 初始设置效果很好 但是 我需要更改包含文件夹中名为 home slider php 的
  • Symfony VS CakePHP:哪一个最接近 PHP [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我主要是一名 Rails 开发人员 但有时 我必须使用 PHP 进行编码 因为 stackoverflow com更喜欢可以回答的问题 我想知道
  • Elm:如何从 JSON API 解码数据

    我有这个数据使用http jsonapi org http jsonapi org format data type prospect id 1 attributes provider user id 1 provider facebook
  • 无法访问 WordPress 中声明的全局变量

    我有以下代码 g value something print g value function get value global g value print g value print get value 当我在独立的 PHP 脚本中运行它
  • Three.js点击单个粒子

    In this example http jsfiddle net agqq96bq 2 您可以看到 2 个可点击的粒子 但它们都受到点击的影响 另外 我只想检测粒子上的点击 而不将它们过滤出场景 像这儿 if intersects len
  • Graphql 将多个查询合并(组合)为一个?

    我正在尝试使用 JavaScript 将多个 GraphQL 查询合并为一个查询 我正在寻找这样的东西 let query3 mergeQueries query1 query2 我们事先不知道哪些查询将被组合 假设我有这样的查询 输入查询
  • 将 html 文本框的值分配给 div 的标题

    line 1
  • 将网站加载到 DIV 中

    当我在文本框中写入 URL 然后单击提交按钮时 如何实际从网站检索数据 我希望将数据放入我拥有的 div 中 这可能吗 我已经尝试过这个 但它不起作用
  • 如果 POST 响应仅包含 ID,如何将数据保存到我的 Ember 存储?

    Ember 数据期望我的服务器在每次成功后返回完整的对象POST 但是 我的 API 只返回一种元对象 其中包含id 当 Ember 收到此对象时 记录中的现有数据将被删除 除了id 例如 当我这样做时 var asset App Asse
  • 如何在单元测试中使用 JSON 发送请求

    我的 Flask 应用程序中有在请求中使用 JSON 的代码 我可以像这样获取 JSON 对象 Request request get json 这一直工作得很好 但是我正在尝试使用 Python 的 unittest 模块创建单元测试 但

随机推荐

  • 将右键菜单添加到 SWT 树中的树项

    如何向 SWT 树中的树项添加右键单击弹出菜单 每个树项都应该启用右键单击 只需使用tree setMenu Menu 就这样 public static void main String args Display display Disp
  • 从 TFS 2010 迁移到 TFS 2012

    我一直在网上搜索关于如何将 2010 年 tfs 集合迁移到新的 tfs 2012 服务器的干净解决方案 但没有成功 请有人协助我完成这些步骤或一个好的博客来实现这个过程 我们想要进行迁移而不是升级的原因是因为我们获得了新硬件 并且希望在升
  • 线程安全的均匀随机数生成器

    我有一些并行的 Fortran90 代码 其中每个线程都需要生成相同的随机数序列 我有一个随机数生成器 它似乎是线程不安全的 因为对于给定的种子 我完全无法在每次运行程序时重复相同的结果 我 几乎 浏览了整个网络 寻找一些线程安全 RNG
  • 带 svg 的 JavaFX 按钮

    我有这个 SVG M421 985 229 833L217 847 25 981c 7 235 7 238 16 94 13 374 29 121 18 416C176 541 2 522 165 407 0 155 318 0H36 54
  • 有没有办法摆脱 ASP.NET Web 部署项目中的 aspx 占位符文件?

    我正在使用一个网络部署项目为了预编译我的ASP NET 3 5 网络项目 它为 aspx 和 ascx 文件中的代码创建一个额外的 DLL 并且 对于每个 aspx 文件 都有一个占位符 aspx 文件 空 需要将其复制到服务器 我想简化部
  • 更新 DOM 与在 Angular 中重新渲染视图

    我正在关注https docs angularjs org guide scope 5 watch列表检测到name属性的变化并通知插值 进而更新 DOM 6 Angular 退出执行上下文 进而退出 keydown 事件以及 JavaSc
  • 为什么循环和 if 语句不需要括号

    我不明白为什么在这种情况下不需要括号 for int i 0 i lt 10 i if num i lt min min num i 为什么在这种情况下我需要括号 int num 10 min for int i 0 i lt 10 i c
  • CreateInstanceAndUnwrap 和域

    我有一个属性 我希望其实例位于其他域中 public ModuleLoader Loader get if loader null loader ModuleLoader myDomain CreateInstanceAndUnwrap t
  • Cloud ML Engine 中部署的重新训练的 inception_v3 模型始终输出相同的预测

    我遵循了代码实验室诗人的 TensorFlow使用 inception v3 进行迁移学习 它生成 retrained graph pb 和 retrained labels txt 文件 可用于在本地进行预测 运行标签图像 py 然后 我
  • 在 Flask-SQLAlchemy 模型上使用函数进行查询会出现 BaseQuery 对象不可调用错误

    我想查询两个日期之间的服务并对它们的价格求和 当我尝试使用时func sum with Services query I get TypeError BaseQuery object is not callable 如何使用 Flask S
  • 最好的 Java 漂亮打印库? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 Java 最好的漂亮打印库是什么 我的意思是一个用于打印带有缩进 中断提示等格式化输出的库 not用于美化 重新格式化 Java 代码本身的库 理想
  • 通过 Jupyter 使用 TensorFlow (Python 3)

    提前道歉 我认为这个问题很令人困惑 我想通过 Jupyter 使用 TensorFlow 和 Python3 内核 然而命令import tensorflow as tf返回错误 ImportError No module named te
  • 如何添加自定义 Material UI 调色板颜色

    我正在尝试建立自己的调色板颜色以匹配我在 Material UI 中的品牌 到目前为止 我只能在将主要颜色和次要颜色用作按钮的背景颜色时才能发挥作用 当我添加自己的变量名称时 例如使用 accent 如 Material UI 网站上的示例
  • 来自另一个应用程序的 django 模板 url

    我必须错过一些愚蠢的东西 我的模板中有一个 url 其中的操作来自另一个应用程序 它不起作用 但我不知道使用其他应用程序的视图功能是否有什么不同 或者我只是在做一些愚蠢的事情 呼叫 模板 呼叫 file html
  • VSCode 自动导入 - 如何强制 Material-UI 全路径导入

    当使用 VSCode 的自动导入功能导入 Material UI 组件时 它将使用命名导入从顶级文件导入 import Button from material ui core 但是 我希望自动导入使用全路径导入反而 import Butt
  • 如何在Ajax请求中发送当前页码

    我正在使用 jQuery DataTable 在表中显示大量数据 我在 Ajax 请求中获取数据页面 如下所示 var pageNo 1 propertyTable dataTable processing true serverSide
  • 更改 Jenkins 服务器的线程数

    我在我的虚拟服务器上安装了 Jenkins 当我看到 htop Jenkins 运行有 30 个线程时 每个线程被允许分配 247MB 内存和最多 1181MB 虚拟内存 因为我只有一个小型虚拟服务器 所以我尝试更改线程数 但我找不到任何配
  • 在 Django 模型的保存方法中引发验证错误

    我不确定如何在模型的保存方法中正确引发验证错误并向用户发回明确的消息 基本上我想知道 if 的每一部分应该如何结束 我想在哪里引发错误 以及它实际保存的地方 def save self args kwargs if not good eno
  • 验证动态添加的字段

    我在单击按钮时使用 jQuery 添加一个表行 add row click function zeile ArtikelTabelle gt tbody append tr td b zeile 1 b td td td tr
  • 如何使用 PHP 将 HTML 转换为 JSON?

    我可以使用将 JSON 转换为 HTMLJsontoHtml图书馆 现在 我需要将当前的 HTML 转换为 JSON 如本网站所示 当查看代码时 我发现以下脚本