我想循环遍历section
以下 JSON 并打印name
其在部分下出现的次数。我该怎么做?
{
"ID": "23",
"section": [
{
"name": "A",
"text": "This is the start of section",
"subsection": [
{
name: "Sub section AA",
text: " This is some text"
},
{
name: "Sub section BB",
text: " This is some text"
}
]
},
{
"name": "B",
"text": "This is the start of the section",
"subsection": [
{
name: "Sub section EE",
text: " This is some text"
},
{
name: "Sub section DD",
text: " This is some text"
}
]
}
]
}
以下是我读取和解析 JSON 的方式:
\documentclass{report}
\usepackage{luacode}
% load json file
\begin{luacode}
local json = require("json")
local file = io.open("sample.json")
tab = json.parse(file:read("*all"))
file:close()
\end{luacode}
\begin{document}
The ID of the document is \directlua{tex.print(tab['ID'])}
Here is the list of all the sections:
\end{document}
json.lua
解析 JSON 的文件(摘自 Henri Menke 的回答):
local lpeg = assert(require("lpeg"))
local C, Cf, Cg, Ct, P, R, S, V =
lpeg.C, lpeg.Cf, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.V
-- number parsing
local digit = R"09"
local dot = P"."
local eE = S"eE"
local sign = S"+-"^-1
local mantissa = digit^1 * dot * digit^0 + dot * digit^1 + digit^1
local exponent = (eE * sign * digit^1)^-1
local real = sign * mantissa * exponent / tonumber
-- optional whitespace
local ws = S" \t\n\r"^0
-- match a literal string surrounded by whitespace
local lit = function(str)
return ws * P(str) * ws
end
-- match a literal string and synthesize an attribute
local attr = function(str,attr)
return ws * P(str) / function() return attr end * ws
end
-- JSON grammar
local json = P{
"object",
value =
V"null_value" +
V"bool_value" +
V"string_value" +
V"real_value" +
V"array" +
V"object",
null_value =
attr("null", nil),
bool_value =
attr("true", true) + attr("false", false),
string_value =
ws * P'"' * C((P'\\"' + 1 - P'"')^0) * P'"' * ws,
real_value =
ws * real * ws,
array =
lit"[" * Ct((V"value" * lit","^-1)^0) * lit"]",
member_pair =
Cg(V"string_value" * lit":" * V"value") * lit","^-1,
object =
lit"{" * Cf(Ct"" * V"member_pair"^0, rawset) * lit"}"
}
return { parse = function(str) return assert(json:match(str)) end }
更新:
我正在尝试使用 for 循环添加动态部分/子部分。例如,
\section{ A }
This is the A section
\addcontentsline{toc}{section}{ Some Sub Section }
\addcontentsline{toc}{section}{Another Sub Section}
\section{ B }
This is the B section
\section{ C }
This is the C section
像章节和小节一样,我还将从读取的 JSON 中动态生成表格。
答案1
您可以迭代返回的 Lua 表:
\documentclass{report}
\usepackage{luacode}
% load json file
\begin{luacode}
local json = require("json")
local file = io.open("sample.json")
tab = json.parse(file:read("*all"))
file:close()
\end{luacode}
\begin{document}
The ID of the document is \directlua{tex.print(tab['ID'])}
Here is the list of all the sections:
\directlua{
for i,k in ipairs(tab["section"]) do
if (i>1) then
tex.sprint (", ")
end
tex.sprint (k.name)
end
}
\end{document}
更新后的 json 无效,我认为这是故意的:
{
"ID": "23",
"section": [
{
"name": "A",
"text": "This is the start of section",
"subsection": [
{
"name": "Sub section AA",
"text": " This is some text"
},
{
"name": "Sub section BB",
"text": " This is some text"
}
]
},
{
"name": "B",
"text": "This is the start of the section",
"subsection": [
{
"name": "Sub section EE",
"text": " This is some text"
},
{
"name": "Sub section DD",
"text": " This is some text"
}
]
}
]
}
因此只需将 Lua 迭代更改为
\documentclass{report}
\usepackage{luacode}
% load json file
\begin{luacode}
local json = require("json")
local file = io.open("sample.json")
tab = json.parse(file:read("*all"))
file:close()
\end{luacode}
\begin{document}
The ID of the document is \directlua{tex.print(tab['ID'])}
\chapter{zzz}
\directlua{
for i,k in ipairs(tab["section"]) do
tex.print ("\string\\section{" .. k.name .. "}")
tex.print (k.text)
for ii,kk in ipairs(k["subsection"]) do
tex.print ("\string\\subsection{" .. kk.name .. "}")
tex.print (kk.text)
end
end
}
\end{document}
更完整的版本需要转义任何 tex 特殊字符并防止出现空字段。