gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 00:17:09 28 4
gpt4 key购买 nike

我可以使用 JsontoHtml 将 JSON 转换为 HTML图书馆。现在,我需要将当前的 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 中使用吗?

请给我建议。

当我尝试根据给出的答案将脚本标记转换为 json 时,出现错误。当我在 json2html 网站上尝试时,它显示如下:enter image description here .. 如何实现相同的解决方案?

最佳答案

如果您能够获得 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);

输出

{
"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是,因为存在 many other possibilities我的简短示例函数没有处理。

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

带脚本的测试用例

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

输出

{
"tag": "html",
"children": [
{
"tag": "head",
"children": [
{
"tag": "script",
"type": "text\/javascript",
"html": "\n alert('hi');\n "
}
]
}
]
}

关于javascript - 如何使用 PHP 将 HTML 转换为 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23062537/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com