diff --git a/lib/src/sparql/json_results.rs b/lib/src/sparql/json_results.rs index 96d54422..352acccc 100644 --- a/lib/src/sparql/json_results.rs +++ b/lib/src/sparql/json_results.rs @@ -1,6 +1,7 @@ //! Implementation of [SPARQL Query Results JSON Format](https://www.w3.org/TR/sparql11-results-json/) use crate::error::{invalid_data_error, invalid_input_error}; +use crate::model::vocab::rdf; use crate::model::*; use crate::sparql::error::EvaluationError; use crate::sparql::model::*; @@ -351,7 +352,9 @@ impl ResultsIterator { state = None; } Some(State::Datatype) => { - datatype = Some(s.to_owned()); + datatype = Some(NamedNode::new(s).map_err(|e| { + invalid_data_error(format!("Invalid datatype value: {}", e)) + })?); state = None; } _ => (), // impossible @@ -386,28 +389,25 @@ impl ResultsIterator { "uri serialization should have a 'value' key", ) })?; - Ok(match datatype { - Some(datatype) => Literal::new_typed_literal( - value, - NamedNode::new(datatype).map_err(|e| { - invalid_data_error(format!( - "Invalid datatype value: {}", - e - )) - })?, - ), - None => match lang { - Some(lang) => { - Literal::new_language_tagged_literal(value, lang) - .map_err(|e| { - invalid_data_error(format!( - "Invalid xml:lang value: {}", - e - )) - })? + Ok(match lang { + Some(lang) => { + if let Some(datatype) = datatype { + if datatype.as_ref() != rdf::LANG_STRING { + return Err(invalid_data_error(format!( + "xml:lang value '{}' provided with the datatype {}", + lang, datatype + ))) + } } - None => Literal::new_simple_literal(value), - }, + Literal::new_language_tagged_literal(value, &lang).map_err(|e| { + invalid_data_error(format!("Invalid xml:lang value '{}': {}", lang, e)) + })? + } + None => if let Some(datatype) = datatype { + Literal::new_typed_literal(value, datatype) + } else { + Literal::new_simple_literal(value) + } } .into()) } diff --git a/lib/src/sparql/xml_results.rs b/lib/src/sparql/xml_results.rs index 5b5120ad..adfea61a 100644 --- a/lib/src/sparql/xml_results.rs +++ b/lib/src/sparql/xml_results.rs @@ -1,6 +1,7 @@ //! Implementation of [SPARQL Query Results XML Format](http://www.w3.org/TR/rdf-sparql-XMLres/) use crate::error::{invalid_data_error, invalid_input_error}; +use crate::model::vocab::rdf; use crate::model::*; use crate::sparql::error::EvaluationError; use crate::sparql::model::*; @@ -628,14 +629,26 @@ fn build_literal( lang: Option, datatype: Option, ) -> Result { - match datatype { - Some(datatype) => Ok(Literal::new_typed_literal(value, datatype)), - None => match lang { - Some(lang) => Literal::new_language_tagged_literal(value, &lang).map_err(|e| { + match lang { + Some(lang) => { + if let Some(datatype) = datatype { + if datatype.as_ref() != rdf::LANG_STRING { + return Err(invalid_data_error(format!( + "xml:lang value '{}' provided with the datatype {}", + lang, datatype + )) + .into()); + } + } + Literal::new_language_tagged_literal(value, &lang).map_err(|e| { invalid_data_error(format!("Invalid xml:lang value '{}': {}", lang, e)).into() - }), - None => Ok(Literal::new_simple_literal(value)), - }, + }) + } + None => Ok(if let Some(datatype) = datatype { + Literal::new_typed_literal(value, datatype) + } else { + Literal::new_simple_literal(value) + }), } }