Module:MwJson: Difference between revisions

Update package: OSW Core
(Update package: OSW Core)
(Update package: OSW Core)
Line 156: Line 156:
elseif type(v) == 'table' then  
elseif type(v) == 'table' then  
if (v[1] == nil) then --key value array = object/dict
if (v[1] == nil) then --key value array = object/dict
local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=v, template=eval_template, mode=mode, stringify_arrays=stringify_arrays})
local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=v, jsonschema=p.defaultArgPath(jsonschema, {"properties", k}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays})
msg = msg .. sub_res.debug_msg
msg = msg .. sub_res.debug_msg
jsondata[k] = sub_res.res
jsondata[k] = sub_res.res
Line 173: Line 173:
end
end
end
end
local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=e, template=eval_template, mode=mode, stringify_arrays=stringify_arrays})
local sub_res = p.expandEmbeddedTemplates({frame=frame, jsondata=e, jsonschema=p.defaultArgPath(jsonschema, {"properties", k, "items"}, {}), template=eval_template, mode=mode, stringify_arrays=stringify_arrays})
msg = msg .. sub_res.debug_msg
msg = msg .. sub_res.debug_msg
if (type(sub_res.res) == 'table') then  
if (type(sub_res.res) == 'table') then  
Line 251: Line 251:
local schema_res = p.walkJsonSchema({jsonschema=jsonschema, categories=categories, mode=mode, recursive=recursive, debug=debug})
local schema_res = p.walkJsonSchema({jsonschema=jsonschema, categories=categories, mode=mode, recursive=recursive, debug=debug})
jsonschema = schema_res.jsonschema
jsonschema = p.expandJsonRef({json=schema_res.jsonschema, debug=debug}).json
--mw.logObject(jsonschema)
--mw.logObject(jsonschema)
Line 275: Line 275:
if (type(v) == "string") then
if (type(v) == "string") then
local vpart = p.splitString(v, ':')
local vpart = p.splitString(v, ':')
if (vpart[1] == "File") then jsonld[k] = mw.getCurrentFrame():callParserFunction( 'filepath', { vpart[2] } ) end --google does not follow redirects via "File":"wiki:Special:Redirect/file/"
if (p.tableLength(vpart) == 2 and vpart[1] == "File") then jsonld[k] = mw.getCurrentFrame():callParserFunction( 'filepath', { vpart[2] } ) end --google does not follow redirects via "File":"wiki:Special:Redirect/file/"
end
end
end
end
Line 434: Line 434:


--[[ test
--[[ test
category = "Category:Hardware"
category = "Category:Entity"
category2 = "Category:OSW80e240a2e17d4ae5adfe6419051aa0bb"
jsonschema = p.expandJsonRef({json=p.loadJson({title=category, slot="jsonschema"}).json}).json
jsonschema =p.walkJsonSchema({jsonschema=p.loadJson({title=category, slot="jsonschema"}).json, debug=true}).jsonschema
mw.logObject(p.buildContext({jsonschema=jsonschema, debug=true}))
or
jsonschema = {
["@context"]={test="level 0"},
properties={
test={
type="object",
["@context"]={test1="level 1"},
properties= {
test= {
type="array",
items= {
type="object",
["@context"]={test2="level 2"}
}
}
}
}
}
}
mw.logObject(p.buildContext({jsonschema=jsonschema, debug=true}))
mw.logObject(p.buildContext({jsonschema=jsonschema, debug=true}))
--]]
--]]
function p.buildContext(args)
function p.buildContext(args)
local schema = p.defaultArg(args.jsonschema, {})
local schema = p.defaultArg(args.jsonschema, {})
--mw.logObject(schema)
local context = p.defaultArg(args.context, schema[p.keys.context])
local context = p.defaultArg(args.context, schema[p.keys.context])
local result = {}
local result = p.defaultArg(args.result, {})
if (context ~= nil) then
if (context ~= nil) then
for k,v in pairs(context) do
for k,v in pairs(context) do
Line 454: Line 475:
result[k] = v
result[k] = v
end
end
end
end
local properties = p.defaultArg(schema.properties, {})
for k,v in pairs(properties) do
local subcontext = nil
if (p.defaultArgPath(properties, {k, 'type'}) == 'object') then
--mw.logObject(properties[k])
subcontext = p.buildContext({jsonschema=properties[k]}).context
elseif (p.defaultArgPath(properties, {k, 'items', 'type'}) == 'object') then
mw.logObject(properties[k]['items'])
subcontext = p.buildContext({jsonschema=properties[k]['items']}).context
end
if (subcontext ~= nil and p.tableLength(subcontext) > 0) then
if (result[k] == nil) then result[k] = {} end
if (type(result[k]) == 'string') then result[k] = {["@id"]=result[k]} end
if (result[k][p.keys.context] == nil) then result[k][p.keys.context] = {} end
result[k][p.keys.context] = p.tableMerge(result[k][p.keys.context], subcontext)
end
end
end
end
Line 493: Line 532:
local properties = {} --semantic properties
local properties = {} --semantic properties
local property_data = {}
local property_data = {}
local context = p.defaultArg(args.context, p.buildContext({jsonschema=schema}).context) --ToDo: subcontext for specific properties
local context = p.defaultArg(args.context, p.buildContext({jsonschema=schema}).context)
local error = ""
local error = ""
if (debug) then mw.logObject(context) end
if (debug) then mw.logObject(context) end
Line 536: Line 575:
--if (debug) then mw.logObject("prop " .. k .. " = " .. mw.dumpObject(v)) end
--if (debug) then mw.logObject("prop " .. k .. " = " .. mw.dumpObject(v)) end
if (mapping_found) then
if (mapping_found) then
local subcontext = p.copy(p.defaultArgPath(context, {k, p.keys.context}, {})) --deepcopy, see also https://phabricator.wikimedia.org/T269990
context = p.tableMerge(context, subcontext) -- pull up nested context
local values = {}
local values = {}
if (v[1] == nil) then --key value array = object/dict
if (v[1] == nil) then --key value array = object/dict
local id = p.getSemanticProperties({jsonschema=schema, jsondata=v, store=true, root=false, debug=debug, context=context, subschema=schema_properties[k], parent_schema_property=property_data[k]}).id --subobject_id
local subproperties_res = p.getSemanticProperties({jsonschema=schema, jsondata=v, store=true, root=false, debug=debug, context=context, subschema=schema_properties[k], parent_schema_property=property_data[k]})
local id = subproperties_res.id --subobject_id
if (id ~= nil) then  
if (id ~= nil) then  
id = mw.title.getCurrentTitle().fullText .. '#' .. id
id = mw.title.getCurrentTitle().fullText .. '#' .. id
table.insert(values, id)  
table.insert(values, id)  
end
end
properties = p.processStatement({subject=properties, statement=subproperties_res.properties, debug=debug}).subject
else --list array
else --list array
for i, e in pairs(v) do
for i, e in pairs(v) do
if (type(e) == 'table') then  
if (type(e) == 'table') then  
local id = p.getSemanticProperties({jsonschema=schema, jsondata=e, store=true, root=false, debug=debug, context=context, subschema=schema_properties[k], parent_schema_property=property_data[k]}).id --subobject_id
local subproperties_res = p.getSemanticProperties({jsonschema=schema, jsondata=e, store=true, root=false, debug=debug, context=context, subschema=schema_properties[k], parent_schema_property=property_data[k]})
local id = subproperties_res.id --subobject_id
if (id ~= nil) then  
if (id ~= nil) then  
id = mw.title.getCurrentTitle().fullText .. '#' .. id
id = mw.title.getCurrentTitle().fullText .. '#' .. id
table.insert(values, id)  
table.insert(values, id)  
end
end
properties = p.processStatement({subject=properties, statement=subproperties_res.properties, debug=debug}).subject
else values = v end --plain strings
else values = v end --plain strings
end
end
Line 589: Line 633:
if (p.tableLength(properties) > 0) then
if (p.tableLength(properties) > 0) then
store_res = mw.smw.subobject( properties, subobjectId ) --store as subobject
store_res = mw.smw.subobject( properties, subobjectId ) --store as subobject
if (debug) then mw.logObject("Store subobject with id " .. subobjectId) end
if (debug) then mw.logObject("Store subobject with id " .. (subobjectId or "<random>")) end
end
end
end
end
Line 599: Line 643:
if (debug) then mw.logObject(error) end
if (debug) then mw.logObject(error) end
return {properties=properties, definitions=property_data, id=subobjectId, context=context, error=error}
return {properties=properties, definitions=property_data, id=subobjectId, context=context, error=error}
end
function p.processStatement(args)
local statement = p.defaultArg(args.statement)
local subject = p.defaultArg(args.subject)
local debug = p.defaultArg(args.debug, false)
-- handle "approved" statements
if (statement["HasSubject"] == nil or statement["HasSubject"][1] == nil or statement["HasSubject"][1] == "") then --implicit subject
if (statement["HasProperty"] ~= nil and statement["HasProperty"][1] ~= nil and statement["HasProperty"][1] ~= "" and statement["HasObject"] ~= nil) then
local property = p.splitString(statement["HasProperty"][1], ":")[2]
if (debug) then
mw.log("Set property " .. property .. " from statement to ")
mw.logObject(statement["HasObject"])
end
if (subject[property] == nil) then subject[property] = {} end
for k, v in pairs(statement["HasObject"]) do table.insert(subject[property], v) end
end
end
return {subject=subject}
end
end


Line 647: Line 711:


-- HELPERS
-- HELPERS
-- expands all $ref
--test: mw.logObject(p.expandJsonRef({json={items={test="value", ["$ref"]="/wiki/JsonSchema:Label?action=raw"}}}).json)
--test: mw.logObject(p.expandJsonRef({json={["$ref"]="/wiki/Category:Item?action=raw&slot=jsonschema"}}).json)
--test: mw.logObject(p.expandJsonRef({json={["$ref"]="/wiki/JsonSchema:Statement?action=raw"}}).json)
function p.expandJsonRef(args)
local json = p.defaultArg(args.json, {})
local debug = p.defaultArg(args.debug, false)
local refs = {}
    for k,v in pairs(json) do
    if (k == "$ref") then
    -- e. g. "/wiki/JsonSchema:Label?action=raw" or "/wiki/Category:Entity?action=raw&slot=jsonschema"
    if string.find(v, "#") then
    if (debug) then mw.logObject("Skip relative reference") end
    else
    local uri = mw.uri.new(v)
    local ref_title = mw.text.split(uri.path, "wiki/", true)[2]
    local ref_slot = uri.query["slot"]
    if (debug) then
    if (ref_slot ~= nil) then mw.logObject("Ref found with title " .. ref_title .. " and slot " .. ref_slot)
    else mw.logObject("Ref found with title " .. ref_title) end
    end
    local ref_json = p.loadJson({title=ref_title, slot=ref_slot}).json
    refs[v] = ref_json
    json[k] = nil
    end
    end
    end
--mw.logObject(refs)
for k,v in pairs(refs) do
json = p.tableMerge(v, json)
end
    for k,v in pairs(json) do
    if type(v) == "table" then
            json[k] = p.expandJsonRef({json=v}).json
        end
    end
   
    return {json=json}
end
function p.defaultArg(arg, default)
function p.defaultArg(arg, default)
if (arg == nil) then  
if (arg == nil) then