How can i return query result into json tree-like?

i'm tring to render a form base on triple, but the result is in flat array,

:用户表单 :render [
        :render [
            :name "用户名" ;
            :type "text"
        ] ;
        :render [
            :name "姓名" ;
            :type "text"
        ] ;
        :render [
            :name "角色" ;
            :type "radio" ;
            :option (:客服 :管理员)
        ]
    ] .
SELECT
      ?name
      ?type
      ?option
      ?value
    WHERE {
      :用户表单 :render ?用户表单 .
      ?用户表单 :render ?元素 .
      ?元素 :name ?name ;
        :type ?type .
      OPTIONAL {
        ?元素 :option ?option .
        ?option rdf:rest*/rdf:first ?value
      }
    }
[
  {
    "name": {
      "type": "literal",
      "value": "姓名"
    },
    "type": {
      "type": "literal",
      "value": "text"
    }
  },
  {
    "name": {
      "type": "literal",
      "value": "角色"
    },
    "type": {
      "type": "literal",
      "value": "radio"
    },
    "value": {
      "type": "uri",
      "value": "http://test/onto#客服"
    },
    "option": {
      "type": "bnode",
      "value": "bnode_02e58914_07f7_4b33_ad0d_896cf787d4d0_224"
    }
  },
  {
    "name": {
      "type": "literal",
      "value": "角色"
    },
    "type": {
      "type": "literal",
      "value": "radio"
    },
    "value": {
      "type": "uri",
      "value": "http://test/onto#管理员"
    },
    "option": {
      "type": "bnode",
      "value": "bnode_02e58914_07f7_4b33_ad0d_896cf787d4d0_224"
    }
  },
  {
    "name": {
      "type": "literal",
      "value": "用户名"
    },
    "type": {
      "type": "literal",
      "value": "text"
    }
  }
]
<form onSubmit={handleSubmit(onSubmit)}>
      {elements.map(({ type, name }) => (
        <div key={name.value}>
          <label htmlFor={name.value}>{name.value}</label>
          <input id={name.value} type={type.value} name={name.value} ref={register} />
        </div>
      ))}
      <div>
        <input type='submit' value='提交' />
      </div>
    </form>

i've tied xml result, but this flat struct is hard to deal

<?xml version=\'1.0\' encoding=\'UTF-8\'?>
<sparql
	xmlns=\'http://www.w3.org/2005/sparql-results#\'>
	<head>
		<variable name=\'name\'/>
		<variable name=\'type\'/>
		<variable name=\'option\'/>
		<variable name=\'value\'/>
	</head>
	<results>
		<result>
			<binding name=\'name\'>
				<literal>姓名</literal>
			</binding>
			<binding name=\'type\'>
				<literal>text</literal>
			</binding>
		</result>
		<result>
			<binding name=\'name\'>
				<literal>角色</literal>
			</binding>
			<binding name=\'type\'>
				<literal>radio</literal>
			</binding>
			<binding name=\'value\'>
				<uri>http://api.stardog.com/客服</uri>
			</binding>
			<binding name=\'option\'>
				<bnode>bnode_a265bd3c_4bc1_4805_85c4_48598f921460_632</bnode>
			</binding>
		</result>
		<result>
			<binding name=\'name\'>
				<literal>角色</literal>
			</binding>
			<binding name=\'type\'>
				<literal>radio</literal>
			</binding>
			<binding name=\'value\'>
				<uri>http://api.stardog.com/管理员</uri>
			</binding>
			<binding name=\'option\'>
				<bnode>bnode_a265bd3c_4bc1_4805_85c4_48598f921460_632</bnode>
			</binding>
		</result>
		<result>
			<binding name=\'name\'>
				<literal>用户名</literal>
			</binding>
			<binding name=\'type\'>
				<literal>text</literal>
			</binding>
		</result>
	</results>
</sparql>

what i expected is like a dom tree, form radio button will have options that nested, i wonder is there a best practice when dealing with sparql result ?

<?xml version=\'1.0\' encoding=\'UTF-8\'?>
<sparql
	xmlns=\'http://www.w3.org/2005/sparql-results#\'>
	<head>
		<variable name=\'name\'/>
		<variable name=\'type\'/>
		<variable name=\'option\'/>
		<variable name=\'value\'/>
	</head>
	<results>
		<result>
			<binding name=\'name\'>
				<literal>姓名</literal>
			</binding>
			<binding name=\'type\'>
				<literal>text</literal>
			</binding>
		</result>
		<result>
			<binding name=\'name\'>
				<literal>角色</literal>
			</binding>
			<binding name=\'type\'>
				<literal>radio</literal>
			</binding>
			
			<binding name=\'option\'>
				<bnode>bnode_a265bd3c_4bc1_4805_85c4_48598f921460_632</bnode>
                               <binding name=\'value\'>
				<uri>http://api.stardog.com/客服</uri>
			</binding>
                            <binding name=\'value\'>
				<uri>http://api.stardog.com/管理员</uri>
			</binding>
			</binding>
		</result>
		
		<result>
			<binding name=\'name\'>
				<literal>用户名</literal>
			</binding>
			<binding name=\'type\'>
				<literal>text</literal>
			</binding>
		</result>
	</results>
</sparql>

Have you looked at GraphQL?

graphql seems doesn't support unicode?

so i have to turn all schema into ascii?

trying to get rdf:List, but stucked

how to get :option (:Admin :Client)

{
    Form {
        render {
            render {
                name
                type
                option @optional 
            }
        }
    }
}
INSERT {
    # 类
    :User a owl:Class .

    :Admin a owl:Class ;
        rdfs:label "管理员" ;
        rdfs:subClassOf :User .

    :Client a owl:Class ;
        rdfs:label "客服" ;
        rdfs:subClassOf :User .

    :Permission a owl:Class .

    # 属性

    :username a owl:DatatypeProperty ;
        a owl:FunctionalProperty .

    :name a owl:DatatypeProperty .

    # 表单
    :userForm a :Form ;
        :render [
            :render [
                :name "用户名" ;
                :type "text"
            ] ;
            :render [
                :name "姓名" ;
                :type "text"
            ] ;
            :render [
                :name "角色" ;
                :type "radio" ;
                :option (:Admin :Client)
            ]
        ] .


    # 创建一些默认用户

    ?crapthings
        a :Client ;
        :username "crapthings" ;
        :name "张翃" .

    ?admin
        a :Admin ;
        :username "admin" ;
        :name "管理员" .
}
WHERE {
    BIND(:user:crapthings as ?crapthings) .
    BIND(:user:admin as ?admin) .
}

The use of latin letters as identifiers appears to be a limitation in the GraphQL specification. We're leveraging the graphql-java library for parsing and as such don't have an easy way around this.

1 Like

What result are you getting for option? The bnode representing the list?

scheme

INSERT {
    # class
    :User a owl:Class .

    :Admin a owl:Class ;
        rdfs:label "Administrator" ;
        rdfs:subClassOf :User .

    :Client a owl:Class ;
        rdfs:label "Client" ;
        rdfs:subClassOf :User .

    :Permission a owl:Class .

    # property

    :username a owl:DatatypeProperty ;
        a owl:FunctionalProperty .

    :name a owl:DatatypeProperty .

    # form

    :userForm a :Form ;
        :hasElement [
            :hasInput [
                :name "username" ;
                :type "text"
            ] ;
            :hasInput [
                :name "name" ;
                :type "text"
            ] ;
            :hasInput [
                :name "role" ;
                :type "radio" ;
                :hasOption (:Admin :Client)
            ]
        ] .


    # create default users

    ?crapthings
        a :Client ;
        :username "crapthings" ;
        :name "zhang hong" .

    ?admin
        a :Admin ;
        :username "admin" ;
        :name "administrator" .
}
WHERE {
    BIND(:user:crapthings as ?crapthings) .
    BIND(:user:admin as ?admin) .
}

query

SELECT
      *
    WHERE {
      :userForm :hasElement ?element .
      ?element :hasInput ?input .
      ?input :name ?name ;
        :type ?type .
      OPTIONAL {
        ?input :hasOption ?list .
        ?list rdf:rest*/rdf:first ?option .
      }
    }

graphql query

{
    Form {
        hasElement {
            hasInput {
                name
                type
                hasOption @optional 
            }
        }
    }
}

and i don't know what to do next, i think it should give me

rdfs:label at least

i'm still watching this video tutorial https://vimeo.com/318530180, but got no clue

Yeah, I see. The list in RDF is represented as several triples. We'll have to add a new directive or something to handle it like this. I'll raise a new feature request.

1 Like

and sometimes might nest in more detail form

:userForm a :Form ;
        :hasElement [
            :hasInput [
                :name "username" ;
                :type "text"
            ] ;
            :hasInput [
                :name "name" ;
                :type "text"
            ] ;
            :hasInput [
                :name "role" ;
                :type "radio" ;
                :hasOption ([
                    :value "something1" ;
                    :label "Administrator"
                    ] [
                    :value "something2" ;
                    :label "Client"
                    ])
            ]
        ] .

That would be fine once we can support the lists. If it's a literal for the option, we should return the value in the array. If it's structured, you would need to list the fields, eg:

option {
  value
  label
}
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.