From 71d62e0a6bb9322cfba72c4a6777adf9eee67ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= Date: Fri, 18 Sep 2020 17:15:12 +0200 Subject: [PATCH 01/22] First version of conversion to ShExML --- build.sbt | 9 +- result.shex | 267 +++++++++++++++--- result.shexml | 63 +++++ .../parser/XMLSchema2ShexParser.scala | 24 -- .../xmlschema2shex/ast/AttributeElement.scala | 0 .../weso/xmlschema2shex/ast/Attributes.scala | 0 .../weso/xmlschema2shex/ast/Restriction.scala | 0 .../ast/RestrictionModifier.scala | 0 .../es/weso/xmlschema2shex/ast/Schema.scala | 0 .../es/weso/xmlschema2shex/ast/Sequence.scala | 0 .../es/weso/xmlschema2shex/ast/Tag.scala | 0 .../check/SemanticChecker.scala | 0 .../decorator/NameDecorator.scala | 0 .../decorator/TypeDecorator.scala | 0 .../generation/CodeGenerator.scala | 0 .../generation/CodeGeneratorShExML.scala | 125 ++++++++ .../generation/NameNormalizator.scala | 22 ++ .../generation/ShExMLPrinter.scala | 66 +++++ .../generation/VarTableBuilder.scala | 36 +++ ...MLSchema2ShExMLDeclarationsConverter.scala | 56 ++++ .../XMLSchema2ShExMLShapesGeneration.scala | 128 +++++++++ .../weso/xmlschema2shex/parser/Parser.scala | 6 +- .../parser/XMLSchema2ShexParser.scala | 40 +++ .../parser/XMLSchemaParser.scala | 0 .../inputoutputtests/OutputSuite.scala | 5 +- 25 files changed, 783 insertions(+), 64 deletions(-) create mode 100644 result.shexml delete mode 100644 src/main/scala-2.11/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/ast/AttributeElement.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/ast/Attributes.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/ast/Restriction.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/ast/RestrictionModifier.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/ast/Schema.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/ast/Sequence.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/ast/Tag.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/check/SemanticChecker.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/decorator/NameDecorator.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/decorator/TypeDecorator.scala (100%) rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/generation/CodeGenerator.scala (100%) create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/generation/NameNormalizator.scala create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/parser/Parser.scala (95%) create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala rename src/main/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala (100%) rename src/test/{scala-2.11 => scala-2.12}/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala (98%) diff --git a/build.sbt b/build.sbt index 58b3d33..6c55f28 100644 --- a/build.sbt +++ b/build.sbt @@ -4,9 +4,12 @@ organization := "es.weso" version := "0.1-SNAPSHOT" -scalaVersion := "2.11.8" +scalaVersion := "2.12.4" -libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.4" -libraryDependencies += "org.scalatest" % "scalatest_2.11" % "3.0.1" % "test" +resolvers += "jitpack" at "https://jitpack.io" + +libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" +libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % "test" +libraryDependencies += "com.github.herminiogg" % "shexml" % "master-SNAPSHOT" diff --git a/result.shex b/result.shex index 159b09f..c9a9c43 100644 --- a/result.shex +++ b/result.shex @@ -1,35 +1,236 @@ - { -:name xs:string {1} ; -:birth_date xs:date {1} ; -:email xs:string {1} ; -:phone xs:string {1} ; -:avatar xs:string {1} ; -:id xs:positiveInteger {1} ; -} - { -:name xs:string {1} ; -:id xs:positiveInteger {1} ; -} - { -:name xs:string {1} ; -:capacity xs:integer {1} ; -:driver * ; -:id xs:positiveInteger {1} ; -} - { -:code xs:string {1} ; -:type xs:string {1} ; -:start_time_operation xs:time {1} ; -:end_time_operation xs:time {1} ; -:count_vehicles xs:integer {0, 10} ; -:map xs:string {1} ; -:start_station @ ? ; -:end_station @ ? ; -:intermediate_stations @ {0, 5} ; -:vehicles_line @ {0, 10} ; -:id xs:positiveInteger {1} ; -} - { -:line @ * ; +ITERATOR lvb_system { + FIELD line +List(ITERATOR line { + FIELD code + xs:string +FIELD type + xs:string +FIELD start_time_operation + xs:time +FIELD end_time_operation + xs:time +FIELD count_vehicles +FIELD xs:integer +FIELD map + xs:string +FIELD start_station +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD end_station +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD intermediate_stations +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD vehicles_line +List(ITERATOR vehicles_line { + FIELD name + xs:string +FIELD capacity + xs:integer +FIELD driver + +:id + xs:positiveIntegerFIELD name + xs:string +FIELD capacity + xs:integer +FIELD driver } +) +:id + xs:positiveIntegerFIELD code + xs:string +FIELD type + xs:string +FIELD start_time_operation + xs:time +FIELD end_time_operation + xs:time +FIELD count_vehicles +FIELD xs:integer +FIELD map + xs:string +FIELD start_station +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD end_station +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD intermediate_stations +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD vehicles_line +List(ITERATOR vehicles_line { + FIELD name + xs:string +FIELD capacity + xs:integer +FIELD driver + +:id + xs:positiveIntegerFIELD name + xs:string +FIELD capacity + xs:integer +FIELD driver + +} +) +} +) +FIELD line +List(ITERATOR line { + FIELD code + xs:string +FIELD type + xs:string +FIELD start_time_operation + xs:time +FIELD end_time_operation + xs:time +FIELD count_vehicles +FIELD xs:integer +FIELD map + xs:string +FIELD start_station +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD end_station +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD intermediate_stations +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD vehicles_line +List(ITERATOR vehicles_line { + FIELD name + xs:string +FIELD capacity + xs:integer +FIELD driver + +:id + xs:positiveIntegerFIELD name + xs:string +FIELD capacity + xs:integer +FIELD driver + +} +) +:id + xs:positiveIntegerFIELD code + xs:string +FIELD type + xs:string +FIELD start_time_operation + xs:time +FIELD end_time_operation + xs:time +FIELD count_vehicles +FIELD xs:integer +FIELD map + xs:string +FIELD start_station +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD end_station +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD intermediate_stations +List(ITERATOR station { + FIELD name + xs:string +:id + xs:positiveIntegerFIELD name + xs:string +} +) +FIELD vehicles_line +List(ITERATOR vehicles_line { + FIELD name + xs:string +FIELD capacity + xs:integer +FIELD driver + +:id + xs:positiveIntegerFIELD name + xs:string +FIELD capacity + xs:integer +FIELD driver + +} +) +} +) +} diff --git a/result.shexml b/result.shexml new file mode 100644 index 0000000..a529349 --- /dev/null +++ b/result.shexml @@ -0,0 +1,63 @@ +ITERATOR lvb_system { + ITERATOR line { + FIELD id + FIELD code + FIELD type + FIELD start_time_operation + FIELD end_time_operation + FIELD count_vehicles + FIELD map + ITERATOR start_station { + FIELD id + FIELD name + } + ITERATOR end_station { + FIELD id + FIELD name + } + ITERATOR intermediate_stations { + FIELD id + FIELD name + } + ITERATOR vehicles_line { + FIELD id + FIELD name + FIELD capacity + FIELD driver + } + } +} +:driver :[] { + :name :[] xs:string ; + :birth_date :[] xs:date ; + :email :[] xs:string ; + :phone :[] xs:string ; + :avatar :[] xs:string ; + :id :[] xs:positiveInteger ; +} +:station :[] { + :name :[] xs:string ; + :id :[] xs:positiveInteger ; +} +:vehicles_line :[] { + :name :[] xs:string ; + :capacity :[] xs:integer ; + :driver @:driver ; + :id :[] xs:positiveInteger ; +} +:line :[] { + :code :[] xs:string ; + :type :[] xs:string ; + :start_time_operation :[] xs:time ; + :end_time_operation :[] xs:time ; + :count_vehicles :[] xs:integer ; + :map :[] xs:string ; + :start_station @:station ; + :end_station @:station ; + :intermediate_stations @:station ; + :vehicles_line @:vehicles_line ; + :id :[] xs:positiveInteger ; +} +:lvb_system :[] { + :line @:line ; +} diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala b/src/main/scala-2.11/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala deleted file mode 100644 index 0e6fb93..0000000 --- a/src/main/scala-2.11/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala +++ /dev/null @@ -1,24 +0,0 @@ -package es.weso.xmlschema2shex.parser - -import es.weso.xmlschema2shex.check.SemanticChecker -import es.weso.xmlschema2shex.decorator.{NameDecorator, TypeDecorator} -import es.weso.xmlschema2shex.generation.CodeGenerator - -/** - * Created by herminio on 5/12/16. - */ -case class XMLSchema2ShexParser() extends XMLSchemaParser { - - def parse(xmlSchema: String, context: Option[String]): String = { - val xmlSchemaWithoutComments = removeComments(xmlSchema) - val schema = parseAll(root, xmlSchemaWithoutComments).get - new SemanticChecker(schema).check() - val decoratedSchema = new TypeDecorator(new NameDecorator(schema).decorate()).decorate() - new CodeGenerator(decoratedSchema).generate() - } - - private def removeComments(xmlSchema: String): String = { - xmlSchema.replaceAll("", "") - } - -} diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/ast/AttributeElement.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/AttributeElement.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/ast/AttributeElement.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/ast/AttributeElement.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/ast/Attributes.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Attributes.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/ast/Attributes.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/ast/Attributes.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/ast/Restriction.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Restriction.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/ast/Restriction.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/ast/Restriction.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/ast/RestrictionModifier.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/RestrictionModifier.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/ast/RestrictionModifier.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/ast/RestrictionModifier.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/ast/Schema.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Schema.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/ast/Schema.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/ast/Schema.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/ast/Sequence.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Sequence.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/ast/Sequence.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/ast/Sequence.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/ast/Tag.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Tag.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/ast/Tag.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/ast/Tag.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/check/SemanticChecker.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/check/SemanticChecker.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/check/SemanticChecker.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/check/SemanticChecker.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/decorator/NameDecorator.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/NameDecorator.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/decorator/NameDecorator.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/decorator/NameDecorator.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/decorator/TypeDecorator.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/TypeDecorator.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/decorator/TypeDecorator.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/decorator/TypeDecorator.scala diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/generation/CodeGenerator.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGenerator.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/generation/CodeGenerator.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGenerator.scala diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala new file mode 100644 index 0000000..18b8c1c --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala @@ -0,0 +1,125 @@ +package es.weso.xmlschema2shex.generation + +import es.weso.xmlschema2shex.ast._ + +/** + * Created by herminio on 5/10/16. + */ +class CodeGeneratorShExML(schema: Schema) { + + def generate(): String = { + generateTypes().mkString("").replaceAll("\"|'", "") + } + + def generateTypes(): List[String] = { + val output = for(tag <- schema.tags) yield tag match { + //case c: ComplexType => generateComplexType(c, c.name) + case e: Element => e.aType.map { + case c: ComplexType => generateComplexType(c, e.name) + case _ => List("") + }.getOrElse(List("")) + case _ => List("") + } + output.flatten.toList + } + + def generateComplexType(complexType: ComplexType, elementName: Option[String]): List[String] = { + val name = complexType.name match { + case Some(aName) => aName + case None => elementName match { + case Some(eName) => eName + case None => throw new Exception("No name to generate the shape") + } + } + + val nestedValues = for(element <- complexType.sequence.elements) yield element match { + case e: Element => List(generateElement(e)) + case _ => List("") // to implement + } + + val iterator = "ITERATOR " + elementName.getOrElse("") + " { \n" + + "\t" + generateSequence(complexType.sequence, complexType.attributesElements) + + nestedValues.flatten.mkString("\n") + "\n}\n" + + + List(iterator) + + /**if(!alreadyGeneratedShape.contains(complexType)) { + alreadyGeneratedShape += complexType + generatedShapes += (complexType -> iterator) + } else { + alreadyGeneratedShape -= complexType + generatedShapes -= complexType + alreadyGeneratedShape += complexType + generatedShapes += (complexType -> iterator) + }*/ + } + + def generateSequence(sequence: Sequence, attributes: List[AttributeElement]): String = { + val elementsString = + (for(element <- sequence.elements) + yield generateElement(element)).mkString("\n") + val attributesString = + (for(attribute <- attributes) + yield generateElement(attribute)).mkString("\n") + elementsString + "\n" + attributesString + } + + def generateElement(element: Typeable): String = { + val elementStart = element.name match { + case Some(theName) => "FIELD " + theName + " <"+ theName +">" + case None => element.ref match { + case Some(ref) => ":" + ref + case None => None + } + } + val typeString = element.aType match { + case Some(theType) => theType match { + case c: ComplexType => { + val name = c.name.getOrElse(c.ref.getOrElse(element.name.getOrElse(element.ref.get))) + generateComplexType(c, Some(name)) + } + case s: SimpleType => { + /**s.restriction match { + case Some(restriction) => restriction.base match { + case Some(name) => name + case None => s.name.getOrElse("") + } + case None => s.name.getOrElse("") + }*/ + val name = s.name.getOrElse("") + "FIELD " + name + " <" + name + ">" + } + case x: XSDType => x match { + case p: XSNMToken => " [\"" + p.value + "\"] " + case _ => " " + x.name + } + } + case None => "" + } + /**val restrictions = element match { + case t: Typeable => generateRestrictions(t).map(r => + if(r.equals("{1}")) "" else " " + r) //implicit boundary + + case _ => Some("") + }*/ + elementStart + " \n" + typeString // + restrictions.get + " ;" + } + + /**def generateRestrictions(element: Typeable): Option[String] = { + val minValue = if(element.minOccurs.isEmpty) Some("1") else element.minOccurs.map(_.replace("'", "")) + val boundaries = minValue.map(min => { + val maxValue = if(element.maxOccurs.isEmpty) Some("1") else element.maxOccurs.map(_.replace("'", "")) + maxValue.map(max => { + if(min.toInt == 0 && max.equals("unbounded")) "*" + else if(min.toInt == 1 && max.equals("unbounded")) "+" + else if(min.toInt == 0 && max.toInt == 1) "?" + else if(min.toInt == max.toInt) "{" + min.toInt + "}" + else "{" + min.toInt + ", " + max.toInt + "}" + }).get + }).getOrElse("") + val pattern = element.pattern.map("PATTERN " + _).getOrElse("") + Some(List(boundaries, pattern).mkString(" ")) + }*/ + +} diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/NameNormalizator.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/NameNormalizator.scala new file mode 100644 index 0000000..c14fa7d --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/NameNormalizator.scala @@ -0,0 +1,22 @@ +package es.weso.xmlschema2shex.generation + +import es.weso.xmlschema2shex.ast.Typeable + +trait NameNormalizator { + + def normalizeName(name: Option[String], ref: Option[String])(implicit varTable: Map[String, Typeable]): String = { + val output = name match { + case Some(theName) => theName + case None => ref match { + case Some(theRef) => varTable.get(theRef).flatMap(_.name).getOrElse("") + case None => throw new Exception("No reference to generate the FIELD") + } + } + normalizeName(output) + } + + def normalizeName(name: String): String = { + name.stripPrefix("\"").stripPrefix("'").stripSuffix("'").stripSuffix("\"") + } + +} diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala new file mode 100644 index 0000000..d1addbc --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala @@ -0,0 +1,66 @@ +package es.weso.xmlschema2shex.generation + +import es.weso.shexml.ast.{Declaration, Field, Iterator, NestedIterator, ObjectElement, PredicateObject, ShExML, Shape, ShapeLink} + +class ShExMLPrinter { + + def print(s: ShExML): String = { + val declarationsToPrint = s.declaration.map { + case Declaration(declarationStatement) => declarationStatement match { + case i: Iterator => print(i, -1) + } + } + val shapesToPrint = s.shape.map { + case s: Shape => print(s, -1) + } + declarationsToPrint.mkString("") + shapesToPrint.mkString("") + } + + def print(i: Iterator, indentation: Int): String = { + val indentationString = generateIndentation(indentation) + indentationString + + "ITERATOR " + i.name.name + " <" + i.queryClause.query + "> {\n" + + i.fields.map(print(_, indentation + 1)).mkString("") + + i.iterators.map(print(_, indentation + 1)).mkString("") + + indentationString + "}\n" + } + + def print(ni: NestedIterator, indentation: Int): String = { + val indentationString = generateIndentation(indentation) + indentationString + + "ITERATOR " + ni.name.name + " <" + ni.queryClause.query + "> {\n" + + ni.fields.map(print(_, indentation + 1)).mkString("") + + ni.iterators.map(print(_, indentation + 1)).mkString("") + + indentationString +"}\n" + } + + def print(f: Field, indentation: Int): String = { + generateIndentation(indentation) + + "FIELD " + f.name.name + " <" + f.queryClause.query + "> \n" + } + + def print(s: Shape, indentation: Int): String = { + generateIndentation(indentation) + + s.shapeName.name + " " + s.shapePrefix + "[] {\n" + + s.predicateObjects.map(po => print(po, indentation + 1)).mkString("") + + "}\n" + } + + def print(po: PredicateObject, indentation: Int): String = { + val objectPart = po.objectOrShapeLink match { + case ObjectElement(prefix, action, literalValue, matcher, dataType, langTag) => literalValue match { + case Some(literal) => prefix + literal + dataType.getOrElse("") + case None => prefix + "[] " + dataType.getOrElse("") + } + case ShapeLink(shape) => "@" + shape.name + } + generateIndentation(indentation) + + po.predicate.prefix + po.predicate.`extension` + " " + objectPart + " ;\n" + } + + private def generateIndentation(indentation: Int): String = { + val identationStrings = (0 to indentation).map(_ => "\t") + identationStrings.mkString("") + } + +} diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala new file mode 100644 index 0000000..5bc6a82 --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala @@ -0,0 +1,36 @@ +package es.weso.xmlschema2shex.generation + +import es.weso.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, Schema, SimpleType, Tag, Typeable} + +import scala.collection.mutable + +class VarTableBuilder(varTable: mutable.Map[String, Typeable]) { + + def visit(schema: Schema): Unit = { + schema.tags.foreach(visit) + } + + def visit(tag: Tag): Unit = tag match { + case e: Element => { + registerVar(e) + e.aType.foreach(visit) + } + case ae: AttributeElement => { + registerVar(ae) + ae.aType.foreach(visit) + } + case c: ComplexType => { + c.sequence.elements.foreach(visit) + c.attributesElements.foreach(visit) + } + + case _ => + } + + private def registerVar(tag: Typeable): Unit = { + if(tag.name.isDefined) { + varTable += ((tag.name.get, tag)) + } + } + +} diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala new file mode 100644 index 0000000..55c0d64 --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala @@ -0,0 +1,56 @@ +package es.weso.xmlschema2shex.generation + +import es.weso.shexml.ast.{AST, Declaration, DeclarationStatement, Field, FieldQuery, Iterator, NestedIterator, ShExML, Var, XmlPath} +import es.weso.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, Schema, Sequence, SimpleType, Typeable} + +class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTable: Map[String, Typeable]) extends NameNormalizator { + + def convert(): ShExML = { + val elements = + for(tag <- schema.tags if tag.isInstanceOf[Element]) yield { + convertElement(tag.asInstanceOf[Element]) + } + val declarations = elements.map(d => Declaration(d.asInstanceOf[DeclarationStatement])) + ShExML(declarations, Nil, Nil) + } + + def convertElement(e: Element): AST = e.aType match { + case Some(nestedType) => nestedType match { + case c: ComplexType => convertComplexType(c, e) + case s: SimpleType => convertSimpleType(s, e) + case _ => generatePlainElement(e) + } + case None => generatePlainElement(e) + } + + private def generatePlainElement(e: Element): Field = { + val name = normalizeName(e.name, e.ref) + Field(Var(name), FieldQuery(name)) + } + + def convertComplexType(c: ComplexType, e: Element): Iterator = { + val attributeElementsFields = c.attributesElements.map(convertAttributeElement) + val sequenceResults = convertSequence(c.sequence) + val iteratorsFromSequence = sequenceResults.filter(_.isInstanceOf[Iterator]).map(_.asInstanceOf[Iterator]) + val nestedIterators = iteratorsFromSequence.map(i => + NestedIterator(i.name, XmlPath(i.queryClause.query.substring(1)), i.fields, i.iterators)) + val fieldsFromSequence = sequenceResults.filter(_.isInstanceOf[Field]).map(_.asInstanceOf[Field]) + val fields = attributeElementsFields ::: fieldsFromSequence + val name = normalizeName(e.name, c.ref) + Iterator(Var(name), XmlPath("/" + name), fields, nestedIterators) + } + + def convertSimpleType(s: SimpleType, e: Element): Field = { + val name = normalizeName(e.name, e.ref) + Field(Var(name), FieldQuery(name)) + } + + def convertAttributeElement(ae: AttributeElement): Field = { + val name = normalizeName(ae.name, ae.ref) + Field(Var(name), FieldQuery(name)) + } + + def convertSequence(s: Sequence): List[AST] = { + s.elements.map(convertElement) + } +} diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala new file mode 100644 index 0000000..61adbe3 --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -0,0 +1,128 @@ +package es.weso.xmlschema2shex.generation + +import es.weso.shexml.ast.{ObjectElement, Predicate, PredicateObject, ShExML, Shape, ShapeLink, ShapeVar} +import es.weso.xmlschema2shex.ast._ + +/** + * Created by herminio on 5/10/16. + */ +class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator { + + val alreadyGeneratedShape = scala.collection.mutable.ListBuffer.empty[ComplexType] + val generatedShapes = scala.collection.mutable.HashMap.empty[ComplexType, Shape] + + def generate(): ShExML = { + ShExML(Nil, Nil, generateTypes()) + } + + def generateTypes(): List[Shape] = { + for(tag <- schema.tags) yield tag match { + case c: ComplexType => generateComplexType(c, c.name) + case e: Element => e.aType.map { + case c: ComplexType => generateComplexType(c, e.name) + case _ => "" + }.getOrElse("") + case _ => "" + } + generatedShapes.values.toList.reverse + } + + def generateComplexType(complexType: ComplexType, elementName: Option[String]): Unit = { + val name = complexType.name match { + case Some(aName) => aName + case None => elementName match { + case Some(eName) => eName + case None => throw new Exception("No name to generate the shape") + } + } + val shapeVar = ShapeVar(":" + normalizeName(name)) + val prefix = ":" // to change + val predicateObjects = generateSequence(complexType.sequence, complexType.attributesElements) + val shape = Shape(shapeVar, prefix, null, predicateObjects, None) + + for(element <- complexType.sequence.elements) yield element.aType match { + case Some(nestedType) => nestedType match { + case c: ComplexType if !alreadyGeneratedShape.contains(c) => generateComplexType(c, element.name) + case _ => "" // to implement + } + case _ => "" + } + + if(!alreadyGeneratedShape.contains(complexType)) { + alreadyGeneratedShape += complexType + generatedShapes += (complexType -> shape) + } else { + alreadyGeneratedShape -= complexType + generatedShapes -= complexType + alreadyGeneratedShape += complexType + generatedShapes += (complexType -> shape) + } + } + + def generateSequence(sequence: Sequence, attributes: List[AttributeElement]): List[PredicateObject] = { + val elementsPredicateObjects = + (for(element <- sequence.elements) + yield generateElement(element)) + val attributesPredicateObjects = + (for(attribute <- attributes) + yield generateElement(attribute)) + elementsPredicateObjects ::: attributesPredicateObjects + } + + def generateElement(element: Typeable): PredicateObject = { + val predicate = element.name match { + case Some(theName) => Predicate(":", normalizeName(theName)) + case None => element.ref match { + case Some(ref) => Predicate(":", normalizeName(ref)) + } + } + val objectOrShapeLink = element.aType match { + case Some(theType) => theType match { + case c: ComplexType => + val name = c.name.getOrElse(c.ref.getOrElse(element.name.getOrElse(element.ref.get))) + ShapeLink(ShapeVar(":" + normalizeName(name))) + case s: SimpleType => { + s.restriction match { + case Some(restriction) => restriction.base match { + case Some(name) => ObjectElement(":", None, None, None, Some(normalizeName(name)), None) + case None => ObjectElement(":", None, None, None, s.name, None) + } + case None => ObjectElement(":", None, None, None, s.name, None) + } + } + case x: XSDType => x match { + case p: XSNMToken => ObjectElement(":", None, None, None, Some(p.value), None) + case _ => ObjectElement(":", None, None, None, Some(x.name), None) + } + } + case None => element.theType match { + case Some(typeName) => ShapeLink(ShapeVar(":" + normalizeName(typeName))) + } + } + val restrictions = element match { + case t: Typeable => generateRestrictions(t).map(r => + if(r.equals("{1}")) "" else " " + r) //implicit boundary + + case _ => Some("") + } + + PredicateObject(predicate, objectOrShapeLink) + } + + def generateRestrictions(element: Typeable): Option[String] = { + val minValue = if(element.minOccurs.isEmpty) Some("1") else element.minOccurs.map(_.replace("'", "")) + val boundaries = minValue.map(min => { + val maxValue = if(element.maxOccurs.isEmpty) Some("1") else element.maxOccurs.map(_.replace("'", "")) + maxValue.map(max => { + if(min.toInt == 0 && max.equals("unbounded")) "*" + else if(min.toInt == 1 && max.equals("unbounded")) "+" + else if(min.toInt == 0 && max.toInt == 1) "?" + else if(min.toInt == max.toInt) "{" + min.toInt + "}" + else "{" + min.toInt + ", " + max.toInt + "}" + }).get + }).getOrElse("") + val pattern = element.pattern.map("PATTERN " + _).getOrElse("") + Some(List(boundaries, pattern).mkString(" ")) + } + +} diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/parser/Parser.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/Parser.scala similarity index 95% rename from src/main/scala-2.11/es/weso/xmlschema2shex/parser/Parser.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/parser/Parser.scala index 5e0ab84..ad5baa3 100644 --- a/src/main/scala-2.11/es/weso/xmlschema2shex/parser/Parser.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/Parser.scala @@ -71,8 +71,10 @@ object Parser extends XMLSchemaParser{ | |""".stripMargin - val output = XMLSchema2ShexParser().parse(xml, None) - val fw = new FileWriter("result.shex") + /**val output = XMLSchema2ShexParser().parse(xml, None) + val fw = new FileWriter("result.shex")*/ + val output = XMLSchema2ShexParser().convertToShExML(xml) + val fw = new FileWriter("result.shexml") fw.write(output) fw.close() println(output) diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala new file mode 100644 index 0000000..d30e2bf --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala @@ -0,0 +1,40 @@ +package es.weso.xmlschema2shex.parser + +import es.weso.shexml.ast.ShExML +import es.weso.xmlschema2shex.ast.Typeable +import es.weso.xmlschema2shex.check.SemanticChecker +import es.weso.xmlschema2shex.decorator.{NameDecorator, TypeDecorator} +import es.weso.xmlschema2shex.generation.{CodeGenerator, CodeGeneratorShExML, ShExMLPrinter, VarTableBuilder, XMLSchema2ShExMLDeclarationsConverter, XMLSchema2ShExMLShapesGeneration} + +import scala.collection.mutable + +/** + * Created by herminio on 5/12/16. + */ +case class XMLSchema2ShexParser() extends XMLSchemaParser { + + def parse(xmlSchema: String, context: Option[String]): String = { + val xmlSchemaWithoutComments = removeComments(xmlSchema) + val schema = parseAll(root, xmlSchemaWithoutComments).get + new SemanticChecker(schema).check() + val decoratedSchema = new TypeDecorator(new NameDecorator(schema).decorate()).decorate() + new CodeGeneratorShExML(decoratedSchema).generate() + } + + def convertToShExML(xmlSchema: String): String = { + val xmlSchemaWithoutComments = removeComments(xmlSchema) + val schema = parseAll(root, xmlSchemaWithoutComments).get + new SemanticChecker(schema).check() + val decoratedSchema = new TypeDecorator(new NameDecorator(schema).decorate()).decorate() + val varTable = mutable.HashMap[String, Typeable]() + new VarTableBuilder(varTable).visit(decoratedSchema) + val declarations = new XMLSchema2ShExMLDeclarationsConverter(decoratedSchema, varTable.toMap).convert().declaration + val shapes = new XMLSchema2ShExMLShapesGeneration(decoratedSchema).generate().shape + new ShExMLPrinter().print(ShExML(declarations, Nil, shapes)) + } + + private def removeComments(xmlSchema: String): String = { + xmlSchema.replaceAll("", "") + } + +} diff --git a/src/main/scala-2.11/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala similarity index 100% rename from src/main/scala-2.11/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala rename to src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala diff --git a/src/test/scala-2.11/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala b/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala similarity index 98% rename from src/test/scala-2.11/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala rename to src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala index 85faebc..1f74d3e 100644 --- a/src/test/scala-2.11/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala +++ b/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala @@ -1,12 +1,13 @@ package es.weso.xmlschema2shex.inputoutputtests import es.weso.xmlschema2shex.parser.XMLSchema2ShexParser -import org.scalatest.{FunSuite, Matchers} +import org.scalatest.funsuite.AnyFunSuite +import org.scalatest.matchers.should.Matchers /** * Created by herminio on 19/12/16. */ -class OutputSuite extends FunSuite with Matchers { +class OutputSuite extends AnyFunSuite with Matchers { test("XML Schema conversion from Microsoft example") { val xml = """ From a0b5d88ae46d820f40231710af05ae9555092167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= Date: Thu, 24 Sep 2020 17:31:11 +0200 Subject: [PATCH 02/22] Improvements in ShExML translation and CLI added --- build.sbt | 1 + purchaseOrder.xsd | 24 +++++++ result.shexml | 42 ++++++------- .../es/weso/xmlschema2shex/Main.scala | 50 +++++++++++++++ .../generation/ShExMLPrinter.scala | 31 +++++++-- ...MLSchema2ShExMLDeclarationsConverter.scala | 7 ++- .../XMLSchema2ShExMLShapesGeneration.scala | 63 +++++++++++-------- .../parser/XMLSchema2ShexParser.scala | 2 +- .../parser/XMLSchemaParser.scala | 52 ++++++++------- 9 files changed, 191 insertions(+), 81 deletions(-) create mode 100644 purchaseOrder.xsd create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala diff --git a/build.sbt b/build.sbt index 6c55f28..68e05e0 100644 --- a/build.sbt +++ b/build.sbt @@ -11,5 +11,6 @@ resolvers += "jitpack" at "https://jitpack.io" libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % "test" libraryDependencies += "com.github.herminiogg" % "shexml" % "master-SNAPSHOT" +libraryDependencies += "info.picocli" % "picocli" % "4.0.4" diff --git a/purchaseOrder.xsd b/purchaseOrder.xsd new file mode 100644 index 0000000..081491e --- /dev/null +++ b/purchaseOrder.xsd @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/result.shexml b/result.shexml index a529349..2c6d71b 100644 --- a/result.shexml +++ b/result.shexml @@ -1,4 +1,5 @@ -ITERATOR lvb_system { +SOURCE example +ITERATOR lvb_system { ITERATOR line { FIELD id FIELD code @@ -27,36 +28,29 @@ ITERATOR lvb_system { } } } -:driver :[] { - :name :[] xs:string ; - :birth_date :[] xs:date ; - :email :[] xs:string ; - :phone :[] xs:string ; - :avatar :[] xs:string ; - :id :[] xs:positiveInteger ; +EXPRESSION iterator +:station :[iterator.line.station.id] { + :name :[iterator.line.station.name] xs:string ; + :id :[iterator.line.station.id] xs:positiveInteger ; } -:station :[] { - :name :[] xs:string ; - :id :[] xs:positiveInteger ; -} -:vehicles_line :[] { - :name :[] xs:string ; - :capacity :[] xs:integer ; +:vehicles_line :[iterator.line.vehicles_line.id] { + :name :[iterator.line.vehicles_line.name] xs:string ; + :capacity :[iterator.line.vehicles_line.capacity] xs:integer ; :driver @:driver ; - :id :[] xs:positiveInteger ; + :id :[iterator.line.vehicles_line.id] xs:positiveInteger ; } -:line :[] { - :code :[] xs:string ; - :type :[] xs:string ; - :start_time_operation :[] xs:time ; - :end_time_operation :[] xs:time ; - :count_vehicles :[] xs:integer ; - :map :[] xs:string ; +:line :[iterator.line.id] { + :code :[iterator.line.code] xs:string ; + :type :[iterator.line.type] xs:string ; + :start_time_operation :[iterator.line.start_time_operation] xs:time ; + :end_time_operation :[iterator.line.end_time_operation] xs:time ; + :count_vehicles :[iterator.line.count_vehicles] xs:integer ; + :map :[iterator.line.map] xs:string ; :start_station @:station ; :end_station @:station ; :intermediate_stations @:station ; :vehicles_line @:vehicles_line ; - :id :[] xs:positiveInteger ; + :id :[iterator.line.id] xs:positiveInteger ; } :lvb_system :[] { :line @:line ; diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala new file mode 100644 index 0000000..3454d01 --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala @@ -0,0 +1,50 @@ +package es.weso.xmlschema2shex + +import java.io.FileWriter +import java.util.concurrent.Callable + +import es.weso.xmlschema2shex.parser.XMLSchema2ShexParser +import picocli.CommandLine +import picocli.CommandLine.{Command, Option} + +object Main { + + def main(args: Array[String]): Unit = { + System.exit(new CommandLine(new Main()).execute(args: _*)) + } +} + +@Command(name = "XMLSchema2ShEx", version = Array("v0.1.1"), + mixinStandardHelpOptions = true, + description = Array("Convert from XML Schema to ShEx and more...")) +class Main extends Callable[Int] { + + @Option(names = Array("-i", "--input"), required = true, description = Array("Path to XML Schema file")) + private var file: String = "" + + @Option(names = Array("-o", "--output"), description = Array("Path where the output file should be created")) + private var output: String = "" + + @Option(names = Array("-s", "--shexml"), description = Array("Generate ShExML scaffold")) + private var shexml: Boolean = false + + override def call(): Int = { + val fileHandler = scala.io.Source.fromFile(file) + try { + val input = fileHandler.mkString + val result = if (shexml) { + XMLSchema2ShexParser().convertToShExML(input) + } else { + XMLSchema2ShexParser().parse(input, None) + } + if (output.nonEmpty) { + val fw = new FileWriter(output) + fw.write(result) + fw.close() + } + println(result) + 1 + } finally { fileHandler.close() } + } + +} diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala index d1addbc..f443014 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala @@ -1,6 +1,6 @@ package es.weso.xmlschema2shex.generation -import es.weso.shexml.ast.{Declaration, Field, Iterator, NestedIterator, ObjectElement, PredicateObject, ShExML, Shape, ShapeLink} +import es.weso.shexml.ast.{Declaration, Expression, Field, Iterator, IteratorQuery, NestedIterator, ObjectElement, PredicateObject, ShExML, Shape, ShapeLink, Source, URL, Var} class ShExMLPrinter { @@ -8,6 +8,8 @@ class ShExMLPrinter { val declarationsToPrint = s.declaration.map { case Declaration(declarationStatement) => declarationStatement match { case i: Iterator => print(i, -1) + case s: Source => print(s) + case e: Expression => print(e) } } val shapesToPrint = s.shape.map { @@ -16,10 +18,14 @@ class ShExMLPrinter { declarationsToPrint.mkString("") + shapesToPrint.mkString("") } + def print(s: Source): String = { + "SOURCE " + s.name.name + " <" + s.path.asInstanceOf[URL].url + ">\n" + } + def print(i: Iterator, indentation: Int): String = { val indentationString = generateIndentation(indentation) indentationString + - "ITERATOR " + i.name.name + " <" + i.queryClause.query + "> {\n" + + "ITERATOR " + i.name.name + " {\n" + i.fields.map(print(_, indentation + 1)).mkString("") + i.iterators.map(print(_, indentation + 1)).mkString("") + indentationString + "}\n" @@ -40,8 +46,12 @@ class ShExMLPrinter { } def print(s: Shape, indentation: Int): String = { + val shapeAction = s.action match { + case Var(action) => action + case _ => "" + } generateIndentation(indentation) + - s.shapeName.name + " " + s.shapePrefix + "[] {\n" + + s.shapeName.name + " " + s.shapePrefix + "[" + shapeAction + "] {\n" + s.predicateObjects.map(po => print(po, indentation + 1)).mkString("") + "}\n" } @@ -50,7 +60,10 @@ class ShExMLPrinter { val objectPart = po.objectOrShapeLink match { case ObjectElement(prefix, action, literalValue, matcher, dataType, langTag) => literalValue match { case Some(literal) => prefix + literal + dataType.getOrElse("") - case None => prefix + "[] " + dataType.getOrElse("") + case None => { + val actionString = if(action.isDefined) action.get.asInstanceOf[Var].name else "" + prefix + "[" + actionString + "] " + dataType.getOrElse("") + } } case ShapeLink(shape) => "@" + shape.name } @@ -58,9 +71,15 @@ class ShExMLPrinter { po.predicate.prefix + po.predicate.`extension` + " " + objectPart + " ;\n" } + def print(exp: Expression): String = { + val iteratorQuery = exp.exp.asInstanceOf[IteratorQuery] + val secondVar = iteratorQuery.composedVar.asInstanceOf[Var] + "EXPRESSION " + exp.name.name + " <" + iteratorQuery.firstVar.name + "." + secondVar.name + ">\n" + } + private def generateIndentation(indentation: Int): String = { - val identationStrings = (0 to indentation).map(_ => "\t") - identationStrings.mkString("") + val indentationStrings = (0 to indentation).map(_ => "\t") + indentationStrings.mkString("") } } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala index 55c0d64..9c30a46 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala @@ -1,6 +1,6 @@ package es.weso.xmlschema2shex.generation -import es.weso.shexml.ast.{AST, Declaration, DeclarationStatement, Field, FieldQuery, Iterator, NestedIterator, ShExML, Var, XmlPath} +import es.weso.shexml.ast.{AST, Declaration, DeclarationStatement, Expression, Field, FieldQuery, Iterator, IteratorQuery, NestedIterator, ShExML, Source, URL, Var, XmlPath} import es.weso.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, Schema, Sequence, SimpleType, Typeable} class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTable: Map[String, Typeable]) extends NameNormalizator { @@ -10,7 +10,10 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl for(tag <- schema.tags if tag.isInstanceOf[Element]) yield { convertElement(tag.asInstanceOf[Element]) } - val declarations = elements.map(d => Declaration(d.asInstanceOf[DeclarationStatement])) + val source = List(Source(Var("example"), URL("http://example.com/example.xml"))) + val iterator = List(Expression(Var("iterator"), IteratorQuery(source.head.name, elements.head.asInstanceOf[Iterator].name))) + val declarations = (source ::: elements ::: iterator) + .map(d => Declaration(d.asInstanceOf[DeclarationStatement])) ShExML(declarations, Nil, Nil) } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala index 61adbe3..c363f00 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -1,6 +1,6 @@ package es.weso.xmlschema2shex.generation -import es.weso.shexml.ast.{ObjectElement, Predicate, PredicateObject, ShExML, Shape, ShapeLink, ShapeVar} +import es.weso.shexml.ast.{ExpOrVar, ObjectElement, Predicate, PredicateObject, ShExML, Shape, ShapeLink, ShapeVar, Var} import es.weso.xmlschema2shex.ast._ /** @@ -17,9 +17,8 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator def generateTypes(): List[Shape] = { for(tag <- schema.tags) yield tag match { - case c: ComplexType => generateComplexType(c, c.name) case e: Element => e.aType.map { - case c: ComplexType => generateComplexType(c, e.name) + case c: ComplexType => generateComplexType(c, e.name, "") case _ => "" }.getOrElse("") case _ => "" @@ -27,7 +26,7 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator generatedShapes.values.toList.reverse } - def generateComplexType(complexType: ComplexType, elementName: Option[String]): Unit = { + def generateComplexType(complexType: ComplexType, elementName: Option[String], precedingNavigation: String): Unit = { val name = complexType.name match { case Some(aName) => aName case None => elementName match { @@ -37,12 +36,19 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator } val shapeVar = ShapeVar(":" + normalizeName(name)) val prefix = ":" // to change - val predicateObjects = generateSequence(complexType.sequence, complexType.attributesElements) - val shape = Shape(shapeVar, prefix, null, predicateObjects, None) + val precedingNavigationString = + if(precedingNavigation.isEmpty) "iterator" else precedingNavigation + "." + normalizeName(name) + val predicateObjects = generateSequence(complexType.sequence, complexType.attributesElements, precedingNavigationString) + val action = predicateObjects.find(po => po.predicate.`extension`.matches("[a-zA-Z0-9]*id[a-zA-Z0-9]*") + && po.objectOrShapeLink.isInstanceOf[ObjectElement]) match { + case Some(id) => id.objectOrShapeLink.asInstanceOf[ObjectElement].action.orNull + case None => null + } + val shape = Shape(shapeVar, prefix, action, predicateObjects, None) for(element <- complexType.sequence.elements) yield element.aType match { case Some(nestedType) => nestedType match { - case c: ComplexType if !alreadyGeneratedShape.contains(c) => generateComplexType(c, element.name) + case c: ComplexType if !alreadyGeneratedShape.contains(c) => generateComplexType(c, element.name, precedingNavigationString) case _ => "" // to implement } case _ => "" @@ -59,17 +65,17 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator } } - def generateSequence(sequence: Sequence, attributes: List[AttributeElement]): List[PredicateObject] = { + def generateSequence(sequence: Sequence, attributes: List[AttributeElement], precedingActionNavigation: String): List[PredicateObject] = { val elementsPredicateObjects = (for(element <- sequence.elements) - yield generateElement(element)) + yield generateElement(element, precedingActionNavigation)) val attributesPredicateObjects = (for(attribute <- attributes) - yield generateElement(attribute)) + yield generateElement(attribute, precedingActionNavigation)) elementsPredicateObjects ::: attributesPredicateObjects } - def generateElement(element: Typeable): PredicateObject = { + def generateElement(element: Typeable, precedingActionNavigation: String): PredicateObject = { val predicate = element.name match { case Some(theName) => Predicate(":", normalizeName(theName)) case None => element.ref match { @@ -77,22 +83,29 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator } } val objectOrShapeLink = element.aType match { - case Some(theType) => theType match { - case c: ComplexType => - val name = c.name.getOrElse(c.ref.getOrElse(element.name.getOrElse(element.ref.get))) - ShapeLink(ShapeVar(":" + normalizeName(name))) - case s: SimpleType => { - s.restriction match { - case Some(restriction) => restriction.base match { - case Some(name) => ObjectElement(":", None, None, None, Some(normalizeName(name)), None) - case None => ObjectElement(":", None, None, None, s.name, None) + case Some(theType) => { + val varString = + if(precedingActionNavigation.isEmpty) Var(normalizeName(predicate.`extension`)) + else Var(precedingActionNavigation + "." + normalizeName(predicate.`extension`)) + val action = Some(varString) + theType match { + case c: ComplexType => + val name = c.name.getOrElse(c.ref.getOrElse(element.name.getOrElse(element.ref.get))) + ShapeLink(ShapeVar(":" + normalizeName(name))) + case s: SimpleType => { + s.restriction match { + case Some(restriction) => restriction.base match { + case Some(name) => + ObjectElement(":", action, None, None, Some(normalizeName(name)), None) + case None => ObjectElement(":", action, None, None, s.name, None) + } + case None => ObjectElement(":", action, None, None, s.name, None) } - case None => ObjectElement(":", None, None, None, s.name, None) } - } - case x: XSDType => x match { - case p: XSNMToken => ObjectElement(":", None, None, None, Some(p.value), None) - case _ => ObjectElement(":", None, None, None, Some(x.name), None) + case x: XSDType => x match { + case p: XSNMToken => ObjectElement(":", action, None, None, Some(p.value), None) + case _ => ObjectElement(":", action, None, None, Some(x.name), None) + } } } case None => element.theType match { diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala index d30e2bf..6a518ca 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala @@ -18,7 +18,7 @@ case class XMLSchema2ShexParser() extends XMLSchemaParser { val schema = parseAll(root, xmlSchemaWithoutComments).get new SemanticChecker(schema).check() val decoratedSchema = new TypeDecorator(new NameDecorator(schema).decorate()).decorate() - new CodeGeneratorShExML(decoratedSchema).generate() + new CodeGenerator(decoratedSchema).generate() } def convertToShExML(xmlSchema: String): String = { diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala index 145f65e..464646c 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala @@ -9,50 +9,50 @@ import scala.util.parsing.combinator._ class XMLSchemaParser extends JavaTokenParsers { - def root: Parser[Schema] = opt("")~""~rep(tags)~"" ^^ { + def root: Parser[Schema] = opt("")~openingTag("schema")~attributes~">"~rep(tags)~closingTag("schema") ^^ { case _ ~ _ ~ attributes ~ _ ~ tags ~ _ => Schema(attributes, tags) } def tags: Parser[Tag] = element | complexType | simpleType | attribute def element: Parser[Element] = - ""~opt(simpleType)~"" ^^ { + openingTag("element")~attributes~">"~opt(simpleType)~closingTag("element") ^^ { case _ ~ attributes ~ _ ~ option ~ _ => Element(attributes, option) - } | ""~opt(complexType)~"" ^^ { + } | openingTag("element")~attributes~">"~opt(complexType)~closingTag("element") ^^ { case _ ~ attributes ~ _ ~ option ~ _ => Element(attributes, option) - } |"" ^^ { + } |openingTag("element")~attributes~"/>" ^^ { case _ ~ attributes ~ _ => Element(attributes, None) } def attribute: Parser[AttributeElement] = - ""~opt(simpleType)~"" ^^ { + openingTag("attribute")~attributes~">"~opt(simpleType)~closingTag("attribute") ^^ { case _ ~ attributes ~ _ ~ option ~ _ => AttributeElement(attributes, option) - } | ""~opt(complexType)~"" ^^ { + } | openingTag("attribute")~attributes~">"~opt(complexType)~closingTag("attribute") ^^ { case _ ~ attributes ~ _ ~ option ~ _ => AttributeElement(attributes, option) - } |"" ^^ { + } |openingTag("attribute")~attributes~"/>" ^^ { case _ ~ attributes ~ _ => AttributeElement(attributes, None) } - def complexType: Parser[ComplexType] = ""~sequence~opt(attributesList)~"" ^^ { + def complexType: Parser[ComplexType] = openingTag("complexType")~attributes~">"~sequence~opt(attributesList)~closingTag("complexType") ^^ { case _ ~ attributes ~ _ ~ sequence ~ attributesList ~_ => ComplexType(attributes, sequence, attributesList.getOrElse(List())) } - def sequence: Parser[Sequence] = ""~rep1(element)~"" ^^ { + def sequence: Parser[Sequence] = fullOpeningTag("sequence")~rep1(element)~closingTag("sequence") ^^ { case _ ~ elements ~ _ => Sequence(elements) } - def complexContent: Parser[Any] = ""~opt(extension)~opt(restriction)~"" + def complexContent: Parser[Any] = fullOpeningTag("complexContent")~opt(extension)~opt(restriction)~closingTag("complexContent") - def extension: Parser[Any] = ""~opt(attributesList)~"" + def extension: Parser[Any] = openingTag("extension")~attributes~">"~opt(attributesList)~closingTag("extension") - def attributesList: Parser[List[AttributeElement]] = rep("") ^^ { + def attributesList: Parser[List[AttributeElement]] = rep(openingTag("attribute")~attributes~"/>") ^^ { _.map { case _ ~ attributes ~ _ => AttributeElement(attributes, None) } } - def simpleType: Parser[SimpleType] = ""~opt(restriction)~"" ^^ { + def simpleType: Parser[SimpleType] = openingTag("simpleType")~attributes~">"~opt(restriction)~closingTag("simpleType") ^^ { case _ ~ attributes ~ _ ~ restriction ~ _ => SimpleType(attributes, restriction) } @@ -63,43 +63,49 @@ class XMLSchemaParser extends JavaTokenParsers { } } - def restriction: Parser[Restriction] = ""~rep(restrictions) ~"" ^^ { + def restriction: Parser[Restriction] = openingTag("restriction")~attributes~">"~rep(restrictions) ~closingTag("restriction") ^^ { case _ ~ attributes ~ _ ~ restrictions ~ _ => Restriction(attributes, Some(restrictions), None, None) } | - ""~sequence~opt(attributesList) ~"" ^^ { + openingTag("restriction")~attributes~">"~sequence~opt(attributesList) ~closingTag("restriction") ^^ { case _ ~ attributes ~_ ~ sequence ~ attributeList ~ _ => Restriction(attributes, None, Some(sequence), attributeList) - } | "" ^^{ + } | openingTag("restriction")~attributes~"/>" ^^{ case _ ~ attributes ~ _ => Restriction(attributes, None, None, None) } def restrictions: Parser[RestrictionModifier] = maxExclusiveRestriction | minExclusiveRestriction | maxInclusiveRestriction | minInclusiveRestriction | patternRestriction | enumeration - def maxExclusiveRestriction: Parser[MaxExclusive] = "" ^^ { + def maxExclusiveRestriction: Parser[MaxExclusive] = openingTag("maxExclusive")~attributes~"/>" ^^ { case _ ~ attributes ~ _ => MaxExclusive(attributes) } - def minExclusiveRestriction: Parser[MinExclusive] = "" ^^ { + def minExclusiveRestriction: Parser[MinExclusive] = openingTag("minExclusive")~attributes~"/>" ^^ { case _ ~ attributes ~ _ => MinExclusive(attributes) } - def maxInclusiveRestriction: Parser[MaxInclusive] = "" ^^ { + def maxInclusiveRestriction: Parser[MaxInclusive] = openingTag("maxInclusive")~attributes~"/>" ^^ { case _ ~ attributes ~ _ => MaxInclusive(attributes) } - def minInclusiveRestriction: Parser[MinInclusive] = "" ^^ { + def minInclusiveRestriction: Parser[MinInclusive] = openingTag("minInclusive")~attributes~"/>" ^^ { case _ ~ attributes ~ _ => MinInclusive(attributes) } - def patternRestriction: Parser[Pattern] = "" ^^ { + def patternRestriction: Parser[Pattern] = openingTag("pattern")~attributes~"/>" ^^ { case _ ~ attributes ~ _ => Pattern(attributes) } - def enumeration: Parser[Enumeration] = "" ^^ { + def enumeration: Parser[Enumeration] = openingTag("enumeration")~attributes~"/>" ^^ { case _ ~ attributes ~ _ => Enumeration(attributes) } - def annotation: Parser[Any] = ""~"".r~"" + def annotation: Parser[Any] = openingTag("annotation")~"".r~closingTag("annotation") + + private def openingTag(name: String) = ("<(xs|xsd):" + name).r + + private def fullOpeningTag(name: String) = ("<(xs|xsd):" + name + ">").r + + private def closingTag(name: String) = ("<\\/(xs|xsd):" + name + ">").r } From 5c0b9386d1ec83a6b442e73e18487a70577484e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= Date: Wed, 14 Oct 2020 11:24:14 +0200 Subject: [PATCH 03/22] Added some improvements to code generation --- .../generation/ShExMLPrinter.scala | 17 ++++++++-- ...MLSchema2ShExMLDeclarationsConverter.scala | 10 ++++-- .../XMLSchema2ShExMLShapesGeneration.scala | 33 +++++++++++-------- .../XMLSchema2ShexCompletionGenerator.scala | 32 ++++++++++++++++++ .../parser/XMLSchema2ShexParser.scala | 5 +-- 5 files changed, 77 insertions(+), 20 deletions(-) create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala index f443014..669815a 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala @@ -1,15 +1,17 @@ package es.weso.xmlschema2shex.generation -import es.weso.shexml.ast.{Declaration, Expression, Field, Iterator, IteratorQuery, NestedIterator, ObjectElement, PredicateObject, ShExML, Shape, ShapeLink, Source, URL, Var} +import es.weso.shexml.ast.{AutoIncrement, Declaration, Expression, Field, Iterator, IteratorQuery, NestedIterator, ObjectElement, PredicateObject, Prefix, ShExML, Shape, ShapeLink, Source, URL, Var} class ShExMLPrinter { def print(s: ShExML): String = { val declarationsToPrint = s.declaration.map { case Declaration(declarationStatement) => declarationStatement match { + case p: Prefix => print(p) case i: Iterator => print(i, -1) case s: Source => print(s) case e: Expression => print(e) + case a: AutoIncrement => print(a) } } val shapesToPrint = s.shape.map { @@ -25,7 +27,7 @@ class ShExMLPrinter { def print(i: Iterator, indentation: Int): String = { val indentationString = generateIndentation(indentation) indentationString + - "ITERATOR " + i.name.name + " {\n" + + "ITERATOR " + i.name.name + " {\n" + i.fields.map(print(_, indentation + 1)).mkString("") + i.iterators.map(print(_, indentation + 1)).mkString("") + indentationString + "}\n" @@ -77,6 +79,17 @@ class ShExMLPrinter { "EXPRESSION " + exp.name.name + " <" + iteratorQuery.firstVar.name + "." + secondVar.name + ">\n" } + def print(autoId: AutoIncrement): String = { + val precedentString = autoId.precedentString.map('"' + _ + "\"" + " + ").getOrElse("") + val closingString = autoId.closingString.map(" + " + '"' + _ + "\"").getOrElse("") + "AUTOINCREMENT " + autoId.name.name + " <" + precedentString + autoId.from + " to " + + autoId.to + " by " + autoId.by + closingString + ">\n" + } + + def print(prefix: Prefix): String = { + "PREFIX " + prefix.name.name + " <" + prefix.url.url + ">\n" + } + private def generateIndentation(indentation: Int): String = { val indentationStrings = (0 to indentation).map(_ => "\t") indentationStrings.mkString("") diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala index 9c30a46..6db4998 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala @@ -1,6 +1,6 @@ package es.weso.xmlschema2shex.generation -import es.weso.shexml.ast.{AST, Declaration, DeclarationStatement, Expression, Field, FieldQuery, Iterator, IteratorQuery, NestedIterator, ShExML, Source, URL, Var, XmlPath} +import es.weso.shexml.ast.{AST, Declaration, DeclarationStatement, Expression, Field, FieldQuery, Iterator, IteratorQuery, NestedIterator, Prefix, ShExML, Source, URL, Var, XmlPath} import es.weso.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, Schema, Sequence, SimpleType, Typeable} class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTable: Map[String, Typeable]) extends NameNormalizator { @@ -10,9 +10,13 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl for(tag <- schema.tags if tag.isInstanceOf[Element]) yield { convertElement(tag.asInstanceOf[Element]) } + val prefix = schema.attributes.attributes.find(_._1 == "targetNamespace") match { + case Some((_, value)) => List(Prefix(Var("tn:"), URL(value.replaceAll("\"", "")))) + case _ => Nil + } val source = List(Source(Var("example"), URL("http://example.com/example.xml"))) - val iterator = List(Expression(Var("iterator"), IteratorQuery(source.head.name, elements.head.asInstanceOf[Iterator].name))) - val declarations = (source ::: elements ::: iterator) + val iterator = List(Expression(Var("exp"), IteratorQuery(source.head.name, elements.head.asInstanceOf[Iterator].name))) + val declarations = (prefix ::: source ::: elements ::: iterator) .map(d => Declaration(d.asInstanceOf[DeclarationStatement])) ShExML(declarations, Nil, Nil) } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala index c363f00..c9fdfac 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -34,15 +34,16 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator case None => throw new Exception("No name to generate the shape") } } - val shapeVar = ShapeVar(":" + normalizeName(name)) - val prefix = ":" // to change + val shapeVar = ShapeVar(getDefaultPrefix() + normalizeName(name)) + val prefix = getDefaultPrefix() val precedingNavigationString = - if(precedingNavigation.isEmpty) "iterator" else precedingNavigation + "." + normalizeName(name) + if(precedingNavigation.isEmpty) "exp" else precedingNavigation + "." + normalizeName(name) val predicateObjects = generateSequence(complexType.sequence, complexType.attributesElements, precedingNavigationString) val action = predicateObjects.find(po => po.predicate.`extension`.matches("[a-zA-Z0-9]*id[a-zA-Z0-9]*") && po.objectOrShapeLink.isInstanceOf[ObjectElement]) match { case Some(id) => id.objectOrShapeLink.asInstanceOf[ObjectElement].action.orNull - case None => null + case None => Var("subjectAutoincrementId") + } val shape = Shape(shapeVar, prefix, action, predicateObjects, None) @@ -77,9 +78,9 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator def generateElement(element: Typeable, precedingActionNavigation: String): PredicateObject = { val predicate = element.name match { - case Some(theName) => Predicate(":", normalizeName(theName)) + case Some(theName) => Predicate(getDefaultPrefix(), normalizeName(theName)) case None => element.ref match { - case Some(ref) => Predicate(":", normalizeName(ref)) + case Some(ref) => Predicate(getDefaultPrefix(), normalizeName(ref)) } } val objectOrShapeLink = element.aType match { @@ -91,25 +92,25 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator theType match { case c: ComplexType => val name = c.name.getOrElse(c.ref.getOrElse(element.name.getOrElse(element.ref.get))) - ShapeLink(ShapeVar(":" + normalizeName(name))) + ShapeLink(ShapeVar(getDefaultPrefix() + normalizeName(name))) case s: SimpleType => { s.restriction match { case Some(restriction) => restriction.base match { case Some(name) => - ObjectElement(":", action, None, None, Some(normalizeName(name)), None) - case None => ObjectElement(":", action, None, None, s.name, None) + ObjectElement(getDefaultPrefix(), action, None, None, Some(normalizeName(name)), None) + case None => ObjectElement(getDefaultPrefix(), action, None, None, s.name, None) } - case None => ObjectElement(":", action, None, None, s.name, None) + case None => ObjectElement(getDefaultPrefix(), action, None, None, s.name, None) } } case x: XSDType => x match { - case p: XSNMToken => ObjectElement(":", action, None, None, Some(p.value), None) - case _ => ObjectElement(":", action, None, None, Some(x.name), None) + case p: XSNMToken => ObjectElement(getDefaultPrefix(), action, None, None, None, None) // that will be pattern but not supported right now in ShExML + case _ => ObjectElement(getDefaultPrefix(), action, None, None, Some(x.name), None) } } } case None => element.theType match { - case Some(typeName) => ShapeLink(ShapeVar(":" + normalizeName(typeName))) + case Some(typeName) => ShapeLink(ShapeVar(getDefaultPrefix() + normalizeName(typeName))) } } val restrictions = element match { @@ -138,4 +139,10 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator Some(List(boundaries, pattern).mkString(" ")) } + private def getDefaultPrefix(): String = { + if(schema.attributes.attributes.exists(_._1 == "targetNamespace")) + "tn:" + else ":" + } + } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala new file mode 100644 index 0000000..1bb5896 --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala @@ -0,0 +1,32 @@ +package es.weso.xmlschema2shex.generation + +import es.weso.shexml.ast.{AutoIncrement, Declaration, Prefix, Shape, URL, Var} + +class XMLSchema2ShexCompletionGenerator(declarations: List[Declaration], shapes: List[Shape]) { + + def generate(): List[Declaration] = { + val declarationsWithAutoIncrement = completeAutoincrement() match { + case Some(declaration) => declarations :+ declaration + case None => declarations + } + completeExamplePrefix() +: declarationsWithAutoIncrement + } + + def completeExamplePrefix(): Declaration = { + Declaration( + Prefix(Var(":"), URL("http://example.org")) + ) + } + + def completeAutoincrement(): Option[Declaration] = { + val needForAutoincrementDeclaration = shapes.exists(s => s.action match { + case Var(name) => name == "subjectAutoincrementId" + case _ => false + }) + if(needForAutoincrementDeclaration) { + Some(Declaration( + AutoIncrement(Var("subjectAutoincrementId"), 1, Int.MaxValue, 1, Some("subject_"), None))) + } else None + } + +} diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala index 6a518ca..0e08d75 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala @@ -4,7 +4,7 @@ import es.weso.shexml.ast.ShExML import es.weso.xmlschema2shex.ast.Typeable import es.weso.xmlschema2shex.check.SemanticChecker import es.weso.xmlschema2shex.decorator.{NameDecorator, TypeDecorator} -import es.weso.xmlschema2shex.generation.{CodeGenerator, CodeGeneratorShExML, ShExMLPrinter, VarTableBuilder, XMLSchema2ShExMLDeclarationsConverter, XMLSchema2ShExMLShapesGeneration} +import es.weso.xmlschema2shex.generation.{CodeGenerator, CodeGeneratorShExML, ShExMLPrinter, VarTableBuilder, XMLSchema2ShExMLDeclarationsConverter, XMLSchema2ShExMLShapesGeneration, XMLSchema2ShexCompletionGenerator} import scala.collection.mutable @@ -30,7 +30,8 @@ case class XMLSchema2ShexParser() extends XMLSchemaParser { new VarTableBuilder(varTable).visit(decoratedSchema) val declarations = new XMLSchema2ShExMLDeclarationsConverter(decoratedSchema, varTable.toMap).convert().declaration val shapes = new XMLSchema2ShExMLShapesGeneration(decoratedSchema).generate().shape - new ShExMLPrinter().print(ShExML(declarations, Nil, shapes)) + val finalDeclarations = new XMLSchema2ShexCompletionGenerator(declarations, shapes).generate() + new ShExMLPrinter().print(ShExML(finalDeclarations, Nil, shapes)) } private def removeComments(xmlSchema: String): String = { From b9492fb1825bf81152daeeac43ffe4a774fc3f33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= Date: Wed, 14 Oct 2020 15:14:51 +0200 Subject: [PATCH 04/22] Fixed error when generating shapes with same complex type --- .../XMLSchema2ShExMLShapesGeneration.scala | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala index c9fdfac..75e984c 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -8,8 +8,7 @@ import es.weso.xmlschema2shex.ast._ */ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator { - val alreadyGeneratedShape = scala.collection.mutable.ListBuffer.empty[ComplexType] - val generatedShapes = scala.collection.mutable.HashMap.empty[ComplexType, Shape] + val generatedShapes = scala.collection.mutable.ListBuffer.empty[Shape] def generate(): ShExML = { ShExML(Nil, Nil, generateTypes()) @@ -23,13 +22,13 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator }.getOrElse("") case _ => "" } - generatedShapes.values.toList.reverse + generatedShapes.toList.reverse } def generateComplexType(complexType: ComplexType, elementName: Option[String], precedingNavigation: String): Unit = { - val name = complexType.name match { + val name = elementName match { case Some(aName) => aName - case None => elementName match { + case None => complexType.name match { case Some(eName) => eName case None => throw new Exception("No name to generate the shape") } @@ -49,21 +48,12 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator for(element <- complexType.sequence.elements) yield element.aType match { case Some(nestedType) => nestedType match { - case c: ComplexType if !alreadyGeneratedShape.contains(c) => generateComplexType(c, element.name, precedingNavigationString) + case c: ComplexType => generateComplexType(c, element.name, precedingNavigationString) case _ => "" // to implement } case _ => "" } - - if(!alreadyGeneratedShape.contains(complexType)) { - alreadyGeneratedShape += complexType - generatedShapes += (complexType -> shape) - } else { - alreadyGeneratedShape -= complexType - generatedShapes -= complexType - alreadyGeneratedShape += complexType - generatedShapes += (complexType -> shape) - } + generatedShapes += shape } def generateSequence(sequence: Sequence, attributes: List[AttributeElement], precedingActionNavigation: String): List[PredicateObject] = { From f402bca2ad3baebb693f7232ec70e5fa8b28cd4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= Date: Wed, 14 Oct 2020 16:49:37 +0200 Subject: [PATCH 05/22] Fixed an error while generating shape links --- .../generation/XMLSchema2ShExMLShapesGeneration.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala index 75e984c..a9b2f57 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -81,7 +81,7 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator val action = Some(varString) theType match { case c: ComplexType => - val name = c.name.getOrElse(c.ref.getOrElse(element.name.getOrElse(element.ref.get))) + val name = element.name.getOrElse(element.ref.getOrElse(c.name.getOrElse(c.ref.get))) ShapeLink(ShapeVar(getDefaultPrefix() + normalizeName(name))) case s: SimpleType => { s.restriction match { From cb5cfc8a7b38b52825c1cad240f1e94d23eac092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= Date: Thu, 15 Oct 2020 15:45:36 +0200 Subject: [PATCH 06/22] Fixed prefix generation while xsd type present --- .../generation/XMLSchema2ShExMLShapesGeneration.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala index a9b2f57..e855b90 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -95,7 +95,7 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator } case x: XSDType => x match { case p: XSNMToken => ObjectElement(getDefaultPrefix(), action, None, None, None, None) // that will be pattern but not supported right now in ShExML - case _ => ObjectElement(getDefaultPrefix(), action, None, None, Some(x.name), None) + case _ => ObjectElement("", action, None, None, Some(x.name), None) } } } From fdae40807a310cbc94f428e58507d775c7933042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= Date: Thu, 15 Oct 2020 16:12:59 +0200 Subject: [PATCH 07/22] Added xsd prefixes in generation --- .../XMLSchema2ShexCompletionGenerator.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala index 1bb5896..797cdce 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala @@ -9,13 +9,16 @@ class XMLSchema2ShexCompletionGenerator(declarations: List[Declaration], shapes: case Some(declaration) => declarations :+ declaration case None => declarations } - completeExamplePrefix() +: declarationsWithAutoIncrement + completePrefixes() ::: declarationsWithAutoIncrement } - def completeExamplePrefix(): Declaration = { - Declaration( - Prefix(Var(":"), URL("http://example.org")) + def completePrefixes(): List[Declaration] = { + List( + Declaration(Prefix(Var(":"), URL("http://example.org"))), + Declaration(Prefix(Var("xs:"), URL("http://www.w3.org/2001/XMLSchema#"))), + Declaration(Prefix(Var("xsd:"), URL("http://www.w3.org/2001/XMLSchema#"))) ) + } def completeAutoincrement(): Option[Declaration] = { From 3d08c97fc78d65537904a7fa0b8b1530025b8536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= Date: Thu, 15 Oct 2020 18:00:25 +0200 Subject: [PATCH 08/22] Added support for xs:all --- purchaseOrderChanges.xsd | 24 + .../xmlschema2shex/ast/ElementsHolder.scala | 14 + .../es/weso/xmlschema2shex/ast/Sequence.scala | 6 - .../es/weso/xmlschema2shex/ast/Tag.scala | 2 +- .../decorator/NameDecorator.scala | 6 +- .../decorator/TypeDecorator.scala | 16 +- .../generation/CodeGenerator.scala | 8 +- .../generation/CodeGeneratorShExML.scala | 8 +- .../generation/VarTableBuilder.scala | 2 +- ...MLSchema2ShExMLDeclarationsConverter.scala | 8 +- .../XMLSchema2ShExMLShapesGeneration.scala | 8 +- .../parser/XMLSchemaParser.scala | 12 +- tei_bare.xsd | 917 ++++++++++++++++++ 13 files changed, 993 insertions(+), 38 deletions(-) create mode 100644 purchaseOrderChanges.xsd create mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/ast/ElementsHolder.scala delete mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/ast/Sequence.scala create mode 100644 tei_bare.xsd diff --git a/purchaseOrderChanges.xsd b/purchaseOrderChanges.xsd new file mode 100644 index 0000000..3c22cc6 --- /dev/null +++ b/purchaseOrderChanges.xsd @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/ElementsHolder.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/ElementsHolder.scala new file mode 100644 index 0000000..80dfed7 --- /dev/null +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/ElementsHolder.scala @@ -0,0 +1,14 @@ +package es.weso.xmlschema2shex.ast + +/** + * Created by herminio on 4/10/16. + */ +sealed trait ElementsHolder { + def elements: List[Element] + def copyInstance(elements: List[Element]): ElementsHolder = this match { + case s: Sequence => s.copy(elements) + case a: All => a.copy(elements) + } +} +case class Sequence(elements: List[Element]) extends ElementsHolder +case class All(elements: List[Element]) extends ElementsHolder \ No newline at end of file diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Sequence.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Sequence.scala deleted file mode 100644 index ff760ba..0000000 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Sequence.scala +++ /dev/null @@ -1,6 +0,0 @@ -package es.weso.xmlschema2shex.ast - -/** - * Created by herminio on 4/10/16. - */ -case class Sequence(elements: List[Element]) \ No newline at end of file diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Tag.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Tag.scala index 3eadef1..60a30c5 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Tag.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Tag.scala @@ -62,7 +62,7 @@ case class AttributeElement(attributes: Attributes, aType: Option[Type]) extends val ref: Option[String] = attributes.attributes.get("ref") } -case class ComplexType(attributes: Attributes, sequence: Sequence, attributesElements: List[AttributeElement]) extends Type { +case class ComplexType(attributes: Attributes, elementsHolder: ElementsHolder, attributesElements: List[AttributeElement]) extends Type { val name = attributes.attributes.get("name") val ref = attributes.attributes.get("ref") } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/NameDecorator.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/NameDecorator.scala index 4f68f2a..12bf826 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/NameDecorator.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/NameDecorator.scala @@ -21,7 +21,7 @@ class NameDecorator(schema: Schema) { } def decorateComplexType(complexType: ComplexType): ComplexType = { - val newElements = complexType.sequence.elements.map(element => { + val newElements = complexType.elementsHolder.elements.map(element => { val newElement = element.aType match { case Some(theType) => theType match { case c: ComplexType => { @@ -41,8 +41,8 @@ class NameDecorator(schema: Schema) { newElement.copy(attributes = newOuterAttributes) } else newElement }) - val newSequence = complexType.sequence.copy(elements = newElements) - complexType.copy(sequence = newSequence) + val newSequence = complexType.elementsHolder.copyInstance(elements = newElements) + complexType.copy(elementsHolder = newSequence) } } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/TypeDecorator.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/TypeDecorator.scala index bd034d6..5218f6a 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/TypeDecorator.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/TypeDecorator.scala @@ -30,20 +30,20 @@ class TypeDecorator(schema: Schema) { } private def decorateComplexType(complexType: ComplexType): ComplexType = { - val newElementSequence = complexType.sequence.elements.map(decorateAllElements) + val newElementSequence = complexType.elementsHolder.elements.map(decorateAllElements) val newAttributesSequence = complexType.attributesElements.map(decorateAllAttributes) - val newSequence = complexType.sequence.copy(elements = newElementSequence) - complexType.copy(sequence = newSequence, attributesElements = newAttributesSequence) + val newSequence = complexType.elementsHolder.copyInstance(elements = newElementSequence) + complexType.copy(elementsHolder = newSequence, attributesElements = newAttributesSequence) } private def decorateAllElements(element: Element): Element = { val newElement = element.copy(aType = searchTypeForElement(element, schema.tags)) val newType = newElement.aType.map({ case c: ComplexType => - val innerElements = for (elem <- c.sequence.elements) yield decorateAllElements(elem) + val innerElements = for (elem <- c.elementsHolder.elements) yield decorateAllElements(elem) val newAttributesSequence = c.attributesElements.map(decorateAllAttributes) - val newSequence = c.sequence.copy(elements = innerElements) - c.copy(sequence = newSequence, attributesElements = newAttributesSequence) + val newSequence = c.elementsHolder.copyInstance(elements = innerElements) + c.copy(elementsHolder = newSequence, attributesElements = newAttributesSequence) case s: SimpleType => s case x: XSDType => x }) @@ -66,7 +66,7 @@ class TypeDecorator(schema: Schema) { else { tag match { case c: ComplexType => - if(c.name.equals(typeName)) Some(c) else searchTypeForElement(element, c.sequence.elements) + if(c.name.equals(typeName)) Some(c) else searchTypeForElement(element, c.elementsHolder.elements) case s: SimpleType => if(s.name.equals(typeName)) Some(s) else result case e: Typeable => { @@ -94,7 +94,7 @@ class TypeDecorator(schema: Schema) { else { tag match { case c: ComplexType => - if(c.name.equals(ref)) Some(c) else searchRefType(ref, c.sequence.elements) + if(c.name.equals(ref)) Some(c) else searchRefType(ref, c.elementsHolder.elements) case s: SimpleType => if(s.name.equals(ref)) Some(s) else result case e: Typeable => diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGenerator.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGenerator.scala index bacac2c..0ad7b0d 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGenerator.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGenerator.scala @@ -34,9 +34,9 @@ class CodeGenerator(schema: Schema) { case None => throw new Exception("No name to generate the shape") } } - val shape = "<" + name + "> { \n" + generateSequence(complexType.sequence, complexType.attributesElements) + "\n}\n" + val shape = "<" + name + "> { \n" + generateSequence(complexType.elementsHolder, complexType.attributesElements) + "\n}\n" - for(element <- complexType.sequence.elements) yield element.aType match { + for(element <- complexType.elementsHolder.elements) yield element.aType match { case Some(nestedType) => nestedType match { case c: ComplexType if !alreadyGeneratedShape.contains(c) => generateComplexType(c, Some(name)) case _ => "" // to implement @@ -55,9 +55,9 @@ class CodeGenerator(schema: Schema) { } } - def generateSequence(sequence: Sequence, attributes: List[AttributeElement]): String = { + def generateSequence(elementsHolder: ElementsHolder, attributes: List[AttributeElement]): String = { val elementsString = - (for(element <- sequence.elements) + (for(element <- elementsHolder.elements) yield generateElement(element)).mkString("\n") val attributesString = (for(attribute <- attributes) diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala index 18b8c1c..478a06a 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala @@ -32,13 +32,13 @@ class CodeGeneratorShExML(schema: Schema) { } } - val nestedValues = for(element <- complexType.sequence.elements) yield element match { + val nestedValues = for(element <- complexType.elementsHolder.elements) yield element match { case e: Element => List(generateElement(e)) case _ => List("") // to implement } val iterator = "ITERATOR " + elementName.getOrElse("") + " { \n" + - "\t" + generateSequence(complexType.sequence, complexType.attributesElements) + + "\t" + generateSequence(complexType.elementsHolder, complexType.attributesElements) + nestedValues.flatten.mkString("\n") + "\n}\n" @@ -55,9 +55,9 @@ class CodeGeneratorShExML(schema: Schema) { }*/ } - def generateSequence(sequence: Sequence, attributes: List[AttributeElement]): String = { + def generateSequence(elementsHolder: ElementsHolder, attributes: List[AttributeElement]): String = { val elementsString = - (for(element <- sequence.elements) + (for(element <- elementsHolder.elements) yield generateElement(element)).mkString("\n") val attributesString = (for(attribute <- attributes) diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala index 5bc6a82..617292d 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala @@ -20,7 +20,7 @@ class VarTableBuilder(varTable: mutable.Map[String, Typeable]) { ae.aType.foreach(visit) } case c: ComplexType => { - c.sequence.elements.foreach(visit) + c.elementsHolder.elements.foreach(visit) c.attributesElements.foreach(visit) } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala index 6db4998..2c95ba9 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala @@ -1,7 +1,7 @@ package es.weso.xmlschema2shex.generation import es.weso.shexml.ast.{AST, Declaration, DeclarationStatement, Expression, Field, FieldQuery, Iterator, IteratorQuery, NestedIterator, Prefix, ShExML, Source, URL, Var, XmlPath} -import es.weso.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, Schema, Sequence, SimpleType, Typeable} +import es.weso.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, ElementsHolder, Schema, Sequence, SimpleType, Typeable} class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTable: Map[String, Typeable]) extends NameNormalizator { @@ -37,7 +37,7 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl def convertComplexType(c: ComplexType, e: Element): Iterator = { val attributeElementsFields = c.attributesElements.map(convertAttributeElement) - val sequenceResults = convertSequence(c.sequence) + val sequenceResults = convertSequence(c.elementsHolder) val iteratorsFromSequence = sequenceResults.filter(_.isInstanceOf[Iterator]).map(_.asInstanceOf[Iterator]) val nestedIterators = iteratorsFromSequence.map(i => NestedIterator(i.name, XmlPath(i.queryClause.query.substring(1)), i.fields, i.iterators)) @@ -57,7 +57,7 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl Field(Var(name), FieldQuery(name)) } - def convertSequence(s: Sequence): List[AST] = { - s.elements.map(convertElement) + def convertSequence(e: ElementsHolder): List[AST] = { + e.elements.map(convertElement) } } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala index e855b90..68853fa 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -37,7 +37,7 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator val prefix = getDefaultPrefix() val precedingNavigationString = if(precedingNavigation.isEmpty) "exp" else precedingNavigation + "." + normalizeName(name) - val predicateObjects = generateSequence(complexType.sequence, complexType.attributesElements, precedingNavigationString) + val predicateObjects = generateSequence(complexType.elementsHolder, complexType.attributesElements, precedingNavigationString) val action = predicateObjects.find(po => po.predicate.`extension`.matches("[a-zA-Z0-9]*id[a-zA-Z0-9]*") && po.objectOrShapeLink.isInstanceOf[ObjectElement]) match { case Some(id) => id.objectOrShapeLink.asInstanceOf[ObjectElement].action.orNull @@ -46,7 +46,7 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator } val shape = Shape(shapeVar, prefix, action, predicateObjects, None) - for(element <- complexType.sequence.elements) yield element.aType match { + for(element <- complexType.elementsHolder.elements) yield element.aType match { case Some(nestedType) => nestedType match { case c: ComplexType => generateComplexType(c, element.name, precedingNavigationString) case _ => "" // to implement @@ -56,9 +56,9 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator generatedShapes += shape } - def generateSequence(sequence: Sequence, attributes: List[AttributeElement], precedingActionNavigation: String): List[PredicateObject] = { + def generateSequence(elementsHolder: ElementsHolder, attributes: List[AttributeElement], precedingActionNavigation: String): List[PredicateObject] = { val elementsPredicateObjects = - (for(element <- sequence.elements) + (for(element <- elementsHolder.elements) yield generateElement(element, precedingActionNavigation)) val attributesPredicateObjects = (for(attribute <- attributes) diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala index 464646c..d1ef431 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala @@ -33,15 +33,21 @@ class XMLSchemaParser extends JavaTokenParsers { case _ ~ attributes ~ _ => AttributeElement(attributes, None) } - def complexType: Parser[ComplexType] = openingTag("complexType")~attributes~">"~sequence~opt(attributesList)~closingTag("complexType") ^^ { + def complexType: Parser[ComplexType] = openingTag("complexType")~attributes~">"~(sequence | all)~opt(attributesList)~closingTag("complexType") ^^ { case _ ~ attributes ~ _ ~ sequence ~ attributesList ~_ => ComplexType(attributes, sequence, attributesList.getOrElse(List())) + case _ ~ attributes ~ _ ~ all ~ attributesList ~_ => + ComplexType(attributes, all, attributesList.getOrElse(List())) } - def sequence: Parser[Sequence] = fullOpeningTag("sequence")~rep1(element)~closingTag("sequence") ^^ { + def sequence: Parser[ElementsHolder] = fullOpeningTag("sequence")~rep1(element)~closingTag("sequence") ^^ { case _ ~ elements ~ _ => Sequence(elements) } + def all: Parser[ElementsHolder] = fullOpeningTag("all")~rep1(element)~closingTag("all") ^^ { + case _ ~ elements ~ _ => All(elements) + } + def complexContent: Parser[Any] = fullOpeningTag("complexContent")~opt(extension)~opt(restriction)~closingTag("complexContent") def extension: Parser[Any] = openingTag("extension")~attributes~">"~opt(attributesList)~closingTag("extension") @@ -67,7 +73,7 @@ class XMLSchemaParser extends JavaTokenParsers { case _ ~ attributes ~ _ ~ restrictions ~ _ => Restriction(attributes, Some(restrictions), None, None) } | openingTag("restriction")~attributes~">"~sequence~opt(attributesList) ~closingTag("restriction") ^^ { - case _ ~ attributes ~_ ~ sequence ~ attributeList ~ _ => Restriction(attributes, None, Some(sequence), attributeList) + case _ ~ attributes ~_ ~ sequence ~ attributeList ~ _ => Restriction(attributes, None, Some(sequence.asInstanceOf[Sequence]), attributeList) } | openingTag("restriction")~attributes~"/>" ^^{ case _ ~ attributes ~ _ => Restriction(attributes, None, None, None) } diff --git a/tei_bare.xsd b/tei_bare.xsd new file mode 100644 index 0000000..24640f7 --- /dev/null +++ b/tei_bare.xsd @@ -0,0 +1,917 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + provides an externally-defined means of identifying the entity (or entities) being named, using a coded value of some kind. + + + + + + + (reference) provides an explicit means of locating a full definition or identity for the entity being named by means of one or more URIs. + + + + + + + + + + + + + + + + + + + + + + supplies the value of the date or time in a standard form, e.g. yyyy-mm-dd. + + + + + + + + + + specifies the earliest possible date for the event in standard form, e.g. yyyy-mm-dd. + + + + + + + + + + specifies the latest possible date for the event in standard form, e.g. yyyy-mm-dd. + + + + + + + + + + indicates the starting point of the period in standard form, e.g. yyyy-mm-dd. + + + + + + + + + + indicates the ending point of the period in standard form, e.g. yyyy-mm-dd. + + + + + + + + + + + + + + + indicates the system or calendar to which the date represented by the content of this element belongs. + + + + + + + supplies a pointer to some location defining a named period of time within which the datable item is understood to have occurred. + + + + + + + + + + points to a description of the rendering or presentation used for this element in the source text. + + + + + + + + + + + + + + + + + + + + + + + + (number) gives a number (or other label) for an element, which is not necessarily unique within the document. + + + + + + + + + + + + + + + may be used to specify further information about the entity referenced by this name in the form of a set of whitespace-separated values, for example the occupation of a person, or the status of a place. + + + + + + + + + + + + + + + + + + + + + (reference to the canonical name) provides a means of locating the canonical form (nym) of the names associated with the object named by the element bearing it. + + + + + + + + + + + + + + + + + + specifies where this item is placed. +Suggested values include: 1] below; 2] bottom; 3] margin; 4] top; 5] opposite; 6] overleaf; 7] above; 8] end; 9] inline; 10] inspace + + + + + + + + + + + + below the line + + + + + + + + + at the foot of the page + + + + + + + + + in the margin (left, right, or both) + + + + + + + + + at the top of the page + + + + + + + + + on the opposite, i.e. facing, page + + + + + + + + + on the other side of the leaf + + + + + + + + + above the line + + + + + + + + + at the end of e.g. chapter or volume. + + + + + + + + + within the body of the text. + + + + + + + + + in a predefined space, for example left by an earlier scribe. + + + + + + + + + + + + + + + + + + + + + + + + + + characterizes the element in some sense, using any convenient classification scheme or typology. + + + + + + + + + + + + provides a sub-categorization of the element, if needed + + + + + + + + + + + + + + + supplies the sort key for this element in an index, list or group which contains it. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (paragraph) marks paragraphs in prose. [3.1. Paragraphs 7.2.5. Speech Contents] + + + + + + + + + + + + contains any sequence of items organized as a list. [3.7. Lists] + + + + + + + + + + + + + + + + + + describes the nature of the items in the list. +Suggested values include: 1] gloss; 2] index; 3] instructions; 4] litany; 5] syllogism + + + + + + + + + + + + + each list item is an entry in an index such as the alphabetical topical index at the back of a print volume. + + + + + + + + + each list item is a step in a sequence of instructions, as in a recipe. + + + + + + + + + each list item is one of a sequence of petitions, supplications or invocations, typically in a religious ritual. + + + + + + + + + each list item is part of an argument consisting of two or more propositions and a final conclusion derived from them. + + + + + + + + + + + + + + + + + contains one component of a list. [3.7. Lists 2.6. The Revision Description] + + + + + + + + + + + + + contains any label or heading used to identify part of a text, typically but not exclusively in a list or glossary. [3.7. Lists] + + + + + + + + + + + + + + (heading) contains any type of heading, for example the title of a section, or the heading of a list, glossary, manuscript description, etc. [4.2.1. Headings and Trailers] + + + + + + + + + + + + + + in a bibliographic reference, contains the name(s) of an author, personal or corporate, of a work; for example in the same form as that provided by a recognized bibliographic name authority. [3.11.2.2. Titles, Authors, and Editors 2.2.1. The Title Statement] + + + + + + + + + + + + + contains a title for any kind of work. [3.11.2.2. Titles, Authors, and Editors 2.2.1. The Title Statement 2.2.5. The Series Statement] + + + + + + + + + + + classifies the title according to some convenient typology. +Sample values include: 1] main; 2] sub (subordinate); 3] alt (alternate); 4] short; 5] desc (descriptive) + + + + + + + + + + + + + + (TEI header) supplies descriptive and declarative metadata associated with a digital resource or set of resources. [2.1.1. The TEI Header and Its Components 15.1. Varieties of Composite Text] + + + + + + + + + + + + + + + + + (file description) contains a full bibliographic description of an electronic file. [2.2. The File Description 2.1.1. The TEI Header and Its Components] + + + + + + + + + + + + + + + (title statement) groups information about the title of a work and those responsible for its content. [2.2.1. The Title Statement 2.2. The File Description] + + + + + + + + + + + + (publication statement) groups information concerning the publication or distribution of an electronic or other text. [2.2.4. Publication, Distribution, Licensing, etc. 2.2. The File Description] + + + + + + + + + (source description) describes the source(s) from which an electronic text was derived or generated, typically a bibliographic description in the case of a digitized text, or a phrase such as "born digital" for a text which has no previous existence. [2.2.7. The Source Description] + + + + + + + + + + + + + + + + + + + + + + + + + + + + contains a single text of any kind, whether unitary or composite, for example a poem or drama, a collection of essays, a novel, a dictionary, or a corpus sample. [4. Default Text Structure 15.1. Varieties of Composite Text] + + + + + + + + + + + + + + (text body) contains the whole body of a single unitary text, excluding any front or back matter. [4. Default Text Structure] + + + + + + + + + + + + + + + + + + + + + (text division) contains a subdivision of the front, body, or back of a text. [4.1. Divisions of the Body] + + + + + + + + + + + + + + + + + + + (front matter) contains any prefatory matter (headers, abstracts, title page, prefaces, dedications, etc.) found at the start of a document, before the main body. [4.6. Title Pages 4. Default Text Structure] + + + + + + + + + + + + + + + + + + (back matter) contains any appendixes, etc. following the main part of a text. [4.7. Back Matter 4. Default Text Structure] + + + + + + + + + + + + + + + + + From f50ffd0aa16098252c4570722879bc674694efa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= Date: Mon, 26 Oct 2020 17:28:43 +0100 Subject: [PATCH 09/22] Added tests for ShExML generation --- ...MLSchema2ShExMLDeclarationsConverter.scala | 8 +- .../XMLSchema2ShExMLShapesGeneration.scala | 18 +- src/test/resources/address.xsd | 22 ++ src/test/resources/purchaseOrderFull.xsd | 60 ++++ src/test/resources/xml1version.xsd | 51 ++++ src/test/resources/xml2version.xsd | 51 ++++ .../inputoutputtests/OutputSuite.scala | 288 ------------------ .../ShExGenerationTests.scala | 106 +++++++ .../ShExMLGenerationTests.scala | 231 ++++++++++++++ 9 files changed, 539 insertions(+), 296 deletions(-) create mode 100644 src/test/resources/address.xsd create mode 100644 src/test/resources/purchaseOrderFull.xsd create mode 100644 src/test/resources/xml1version.xsd create mode 100644 src/test/resources/xml2version.xsd delete mode 100644 src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala create mode 100644 src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala create mode 100644 src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala index 2c95ba9..b34ea7b 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala @@ -7,9 +7,9 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl def convert(): ShExML = { val elements = - for(tag <- schema.tags if tag.isInstanceOf[Element]) yield { + (for(tag <- schema.tags if tag.isInstanceOf[Element] && tag.asInstanceOf[Element].aType.exists(_.isInstanceOf[ComplexType])) yield { convertElement(tag.asInstanceOf[Element]) - } + }).filter(t => t.isInstanceOf[Iterator]) val prefix = schema.attributes.attributes.find(_._1 == "targetNamespace") match { case Some((_, value)) => List(Prefix(Var("tn:"), URL(value.replaceAll("\"", "")))) case _ => Nil @@ -43,7 +43,9 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl NestedIterator(i.name, XmlPath(i.queryClause.query.substring(1)), i.fields, i.iterators)) val fieldsFromSequence = sequenceResults.filter(_.isInstanceOf[Field]).map(_.asInstanceOf[Field]) val fields = attributeElementsFields ::: fieldsFromSequence - val name = normalizeName(e.name, c.ref) + val nameOption = if(e.name.isDefined) e.name else e.ref + val refOption = if(c.ref.isDefined) c.ref else c.name + val name = normalizeName(nameOption, refOption) Iterator(Var(name), XmlPath("/" + name), fields, nestedIterators) } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala index 68853fa..aa950fc 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -48,12 +48,20 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator for(element <- complexType.elementsHolder.elements) yield element.aType match { case Some(nestedType) => nestedType match { - case c: ComplexType => generateComplexType(c, element.name, precedingNavigationString) + case c: ComplexType => { + val name = if(element.name.isDefined) element.name else element.ref + generateComplexType(c, name, precedingNavigationString) + } case _ => "" // to implement } case _ => "" } - generatedShapes += shape + if(!generatedShapes.exists(s => s.shapeName.name == shape.shapeName.name)) + generatedShapes += shape + else { + val index = generatedShapes.indexOf(generatedShapes.find(s => s.shapeName.name == shape.shapeName.name).get) + generatedShapes.update(index, shape) + } } def generateSequence(elementsHolder: ElementsHolder, attributes: List[AttributeElement], precedingActionNavigation: String): List[PredicateObject] = { @@ -87,10 +95,10 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator s.restriction match { case Some(restriction) => restriction.base match { case Some(name) => - ObjectElement(getDefaultPrefix(), action, None, None, Some(normalizeName(name)), None) - case None => ObjectElement(getDefaultPrefix(), action, None, None, s.name, None) + ObjectElement("", action, None, None, Some(normalizeName(name)), None) + case None => ObjectElement("", action, None, None, s.name, None) } - case None => ObjectElement(getDefaultPrefix(), action, None, None, s.name, None) + case None => ObjectElement("", action, None, None, s.name, None) } } case x: XSDType => x match { diff --git a/src/test/resources/address.xsd b/src/test/resources/address.xsd new file mode 100644 index 0000000..c52bbef --- /dev/null +++ b/src/test/resources/address.xsd @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/purchaseOrderFull.xsd b/src/test/resources/purchaseOrderFull.xsd new file mode 100644 index 0000000..d32757e --- /dev/null +++ b/src/test/resources/purchaseOrderFull.xsd @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/xml1version.xsd b/src/test/resources/xml1version.xsd new file mode 100644 index 0000000..25e2f2b --- /dev/null +++ b/src/test/resources/xml1version.xsd @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/xml2version.xsd b/src/test/resources/xml2version.xsd new file mode 100644 index 0000000..5724548 --- /dev/null +++ b/src/test/resources/xml2version.xsd @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala b/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala deleted file mode 100644 index 1f74d3e..0000000 --- a/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/OutputSuite.scala +++ /dev/null @@ -1,288 +0,0 @@ -package es.weso.xmlschema2shex.inputoutputtests - -import es.weso.xmlschema2shex.parser.XMLSchema2ShexParser -import org.scalatest.funsuite.AnyFunSuite -import org.scalatest.matchers.should.Matchers - -/** - * Created by herminio on 19/12/16. - */ -class OutputSuite extends AnyFunSuite with Matchers { - - test("XML Schema conversion from Microsoft example") { - val xml = """ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - """ - val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") - output should include (""" { - |:shipTo @ {1} ; - |:billTo @ {1} ; - |:comment xs:string ? ; - |:items @ {1} ; - |:orderDate xs:date {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include (""" { - |:name xs:string {1} ; - |:street xs:string {1} ; - |:city xs:string {1} ; - |:state xs:string {1} ; - |:zip xs:decimal {1} ; - |:country [US] {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include (""" { - |:item @ * ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include (""" { - |:productName xs:string {1} ; - |:quantity xs:positiveInteger {1, 99} ; - |:USPrice xs:decimal {1} ; - |:comment xs:string ? ; - |:shipDate xs:date ? ; - |:partNum xs:string {1} PATTERN \\d{3}-[A-Z]{2} ; - |}""".stripMargin.replaceAll(" |\n", "")) - } - - test("XML Schema conversion for addresses") { - val xml = - """ - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - """.stripMargin - val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") - output should include(""" { - |:address @
+ ; - |}""".stripMargin.replaceAll(" |\n", "")) - - output should include("""
{ - |:name xs:string ? ; - |:street xs:string ? ; - |}""".stripMargin.replaceAll(" |\n", "")) - - } - - test("""Xml1 version""") { - val xml = """ - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |""".stripMargin - val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") - output should include(""" { - |:orderperson xs:string {1} ; - |:shipto @ {1} ; - |:item @ + ; - |:orderid xs:string {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include(""" { - |:title xs:string {1} ; - |:note xs:string ? ; - |:quantity xs:positiveInteger {1} ; - |:price xs:decimal {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include(""" { - |:name xs:string {1} ; - |:address xs:string {1} ; - |:city xs:string {1} ; - |:country xs:string {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - } - - test("""Xml2 version""") { - val xml = """ - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |""".stripMargin - val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") - output should include(""" { - |:orderperson xs:string {1} ; - |:shipto @ {1} ; - |:item @ + ; - |:orderid xs:string {1} PATTERN [0-9]{6} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include(""" { - |:title xs:string {1} ; - |:note xs:string ? ; - |:quantity xs:positiveInteger {1} ; - |:price xs:decimal {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include(""" { - |:name xs:string {1} ; - |:address xs:string {1} ; - |:city xs:string {1} ; - |:country xs:string {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - } - - -} diff --git a/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala b/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala new file mode 100644 index 0000000..869b7a4 --- /dev/null +++ b/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala @@ -0,0 +1,106 @@ +package es.weso.xmlschema2shex.inputoutputtests + +import es.weso.xmlschema2shex.parser.XMLSchema2ShexParser +import org.scalatest.funsuite.AnyFunSuite +import org.scalatest.matchers.should.Matchers + +import scala.io.Source + +/** + * Created by herminio on 19/12/16. + */ +class ShExGenerationTests extends AnyFunSuite with Matchers { + + test("XML Schema conversion from Microsoft example") { + val xml = Source.fromResource("purchaseOrderFull.xsd").mkString + val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") + output should include (""" { + |:shipTo @ {1} ; + |:billTo @ {1} ; + |:comment xs:string ? ; + |:items @ {1} ; + |:orderDate xs:date {1} ; + |}""".stripMargin.replaceAll(" |\n", "")) + output should include (""" { + |:name xs:string {1} ; + |:street xs:string {1} ; + |:city xs:string {1} ; + |:state xs:string {1} ; + |:zip xs:decimal {1} ; + |:country [US] {1} ; + |}""".stripMargin.replaceAll(" |\n", "")) + output should include (""" { + |:item @ * ; + |}""".stripMargin.replaceAll(" |\n", "")) + output should include (""" { + |:productName xs:string {1} ; + |:quantity xs:positiveInteger {1, 99} ; + |:USPrice xs:decimal {1} ; + |:comment xs:string ? ; + |:shipDate xs:date ? ; + |:partNum xs:string {1} PATTERN \\d{3}-[A-Z]{2} ; + |}""".stripMargin.replaceAll(" |\n", "")) + } + + test("XML Schema conversion for addresses") { + val xml = Source.fromResource("address.xsd").mkString + val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") + output should include(""" { + |:address @
+ ; + |}""".stripMargin.replaceAll(" |\n", "")) + + output should include("""
{ + |:name xs:string ? ; + |:street xs:string ? ; + |}""".stripMargin.replaceAll(" |\n", "")) + + } + + test("""Xml1 version""") { + val xml = Source.fromResource("xml1version.xsd").mkString + val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") + output should include(""" { + |:orderperson xs:string {1} ; + |:shipto @ {1} ; + |:item @ + ; + |:orderid xs:string {1} ; + |}""".stripMargin.replaceAll(" |\n", "")) + output should include(""" { + |:title xs:string {1} ; + |:note xs:string ? ; + |:quantity xs:positiveInteger {1} ; + |:price xs:decimal {1} ; + |}""".stripMargin.replaceAll(" |\n", "")) + output should include(""" { + |:name xs:string {1} ; + |:address xs:string {1} ; + |:city xs:string {1} ; + |:country xs:string {1} ; + |}""".stripMargin.replaceAll(" |\n", "")) + } + + test("""Xml2 version""") { + val xml = Source.fromResource("xml2version.xsd").mkString + val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") + output should include(""" { + |:orderperson xs:string {1} ; + |:shipto @ {1} ; + |:item @ + ; + |:orderid xs:string {1} PATTERN [0-9]{6} ; + |}""".stripMargin.replaceAll(" |\n", "")) + output should include(""" { + |:title xs:string {1} ; + |:note xs:string ? ; + |:quantity xs:positiveInteger {1} ; + |:price xs:decimal {1} ; + |}""".stripMargin.replaceAll(" |\n", "")) + output should include(""" { + |:name xs:string {1} ; + |:address xs:string {1} ; + |:city xs:string {1} ; + |:country xs:string {1} ; + |}""".stripMargin.replaceAll(" |\n", "")) + } + + +} diff --git a/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala b/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala new file mode 100644 index 0000000..9455d9c --- /dev/null +++ b/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala @@ -0,0 +1,231 @@ +package es.weso.xmlschema2shex.inputoutputtests + +import es.weso.xmlschema2shex.parser.XMLSchema2ShexParser +import org.scalatest.funsuite.AnyFunSuite +import org.scalatest.matchers.should.Matchers + +import scala.io.Source + +/** + * Created by herminio on 19/12/16. + */ +class ShExMLGenerationTests extends AnyFunSuite with Matchers { + + test("Xml1 version") { + val xml = Source.fromResource("xml1version.xsd").mkString + val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll(" |\n|\t", "") + output should include ("""PREFIX : + |PREFIX xs: + |PREFIX xsd: """.stripMargin.replaceAll(" |\n|\t", "")) + output should include (""" + |SOURCE example + |""".stripMargin.replaceAll(" |\n|\t", "")) + output should include ("""ITERATOR shipto { + | FIELD name + | FIELD address
+ | FIELD city + | FIELD country + |} + |ITERATOR item { + | FIELD title + | FIELD note <note> + | FIELD quantity <quantity> + | FIELD price <price> + |} + |ITERATOR shiporder <xpath: /shiporder> { + | FIELD orderid <orderid> + | FIELD orderperson <orderperson> + | ITERATOR shipto <shipto> { + | FIELD name <name> + | FIELD address <address> + | FIELD city <city> + | FIELD country <country> + | } + | ITERATOR item <item> { + | FIELD title <title> + | FIELD note <note> + | FIELD quantity <quantity> + | FIELD price <price> + | } + |} + |EXPRESSION exp <example.shipto> + |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll(" |\n|\t", "")) + output should include (""":shiporder :[exp.orderid] { + | :orderperson [exp.orderperson] xs:string ; + | :shipto @:shipto ; + | :item @:item ; + | :orderid [exp.orderid] xs:string ; + |} + |:item :[subjectAutoincrementId] { + | :title [exp.item.title] xs:string ; + | :note [exp.item.note] xs:string ; + | :quantity [exp.item.quantity] xs:positiveInteger ; + | :price [exp.item.price] xs:decimal ; + |} + |:shipto :[subjectAutoincrementId] { + | :name [exp.shipto.name] xs:string ; + | :address [exp.shipto.address] xs:string ; + | :city [exp.shipto.city] xs:string ; + | :country [exp.shipto.country] xs:string ; + |}""".stripMargin.replaceAll(" |\n|\t", "")) + } + + test("""Xml2 version""") { + val xml = Source.fromResource("xml2version.xsd").mkString + val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll(" |\n|\t", "") + output should include ("""PREFIX : <http://example.org> + |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> + |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll(" |\n|\t", "")) + output should include (""" + |SOURCE example <http://example.com/example.xml> + |""".stripMargin.replaceAll(" |\n|\t", "")) + output should include ("""ITERATOR shiporder <xpath: /shiporder> { + | FIELD orderid <orderid> + | FIELD orderperson <orderperson> + | ITERATOR shipto <shipto> { + | FIELD name <name> + | FIELD address <address> + | FIELD city <city> + | FIELD country <country> + | } + | ITERATOR item <item> { + | FIELD title <title> + | FIELD note <note> + | FIELD quantity <quantity> + | FIELD price <price> + | } + |} + |EXPRESSION exp <example.shiporder> + |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll(" |\n|\t", "")) + output should include (""":shiporder :[exp.orderid] { + | :orderperson [exp.orderperson] xs:string ; + | :shipto @:shipto ; + | :item @:item ; + | :orderid [exp.orderid] xs:string ; + |} + |:item :[subjectAutoincrementId] { + | :title [exp.item.title] xs:string ; + | :note [exp.item.note] xs:string ; + | :quantity [exp.item.quantity] xs:positiveInteger ; + | :price [exp.item.price] xs:decimal ; + |} + |:shipto :[subjectAutoincrementId] { + | :name [exp.shipto.name] xs:string ; + | :address [exp.shipto.address] xs:string ; + | :city [exp.shipto.city] xs:string ; + | :country [exp.shipto.country] xs:string ; + |}""".stripMargin.replaceAll(" |\n|\t", "")) + } + + test("XML Schema conversion for addresses") { + val xml = Source.fromResource("address.xsd").mkString + val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll(" |\n|\t", "") + output should include ("""PREFIX : <http://example.org> + |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> + |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll(" |\n|\t", "")) + output should include (""" + |SOURCE example <http://example.com/example.xml> + |""".stripMargin.replaceAll(" |\n|\t", "")) + output should include ("""ITERATOR addresses <xpath: /addresses> { + | ITERATOR address <address> { + | FIELD name <name> + | FIELD street <street> + | } + |} + |ITERATOR address <xpath: /address> { + | FIELD name <name> + | FIELD street <street> + |} + |EXPRESSION exp <example.addresses> + |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll(" |\n|\t", "")) + output should include (""":addresses :[subjectAutoincrementId] { + | :address @:address ; + |} + |:address :[subjectAutoincrementId] { + | :name [exp.name] xs:string ; + | :street [exp.street] xs:string ; + |}""".stripMargin.replaceAll(" |\n|\t", "")) + } + + test("""XML Schema conversion from Microsoft example""") { + val xml = Source.fromResource("purchaseOrderFull.xsd").mkString + val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll(" |\n|\t", "") + output should include ("""PREFIX : <http://example.org> + |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> + |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> + |PREFIX tn: <http://tempuri.org/po.xsd>""".stripMargin.replaceAll(" |\n|\t", "")) + output should include (""" + |SOURCE example <http://example.com/example.xml> + |""".stripMargin.replaceAll(" |\n|\t", "")) + output should include ("""ITERATOR purchaseOrder <xpath: /purchaseOrder> { + | FIELD orderDate <orderDate> + | FIELD comment <comment> + | ITERATOR shipTo <shipTo> { + | FIELD country <country> + | FIELD name <name> + | FIELD street <street> + | FIELD city <city> + | FIELD state <state> + | FIELD zip <zip> + | } + | ITERATOR billTo <billTo> { + | FIELD country <country> + | FIELD name <name> + | FIELD street <street> + | FIELD city <city> + | FIELD state <state> + | FIELD zip <zip> + | } + | ITERATOR items <items> { + | ITERATOR item <item> { + | FIELD partNum <partNum> + | FIELD productName <productName> + | FIELD quantity <quantity> + | FIELD USPrice <USPrice> + | FIELD comment <comment> + | FIELD shipDate <shipDate> + | } + | } + |} + |EXPRESSION exp <example.purchaseOrder> + |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll(" |\n|\t", "")) + output should include ("""tn:purchaseOrder tn:[subjectAutoincrementId] { + | tn:shipTo @tn:shipTo ; + | tn:billTo @tn:billTo ; + | tn:comment [exp.comment] xs:string ; + | tn:items @tn:items ; + | tn:orderDate [exp.orderDate] xs:date ; + |} + |tn:items tn:[subjectAutoincrementId] { + | tn:item @tn:item ; + |} + |tn:item tn:[subjectAutoincrementId] { + | tn:productName [exp.items.item.productName] xs:string ; + | tn:quantity [exp.items.item.quantity] xs:positiveInteger ; + | tn:USPrice [exp.items.item.USPrice] xs:decimal ; + | tn:comment [exp.items.item.comment] xs:string ; + | tn:shipDate [exp.items.item.shipDate] xs:date ; + | tn:partNum [exp.items.item.partNum] xs:string ; + |} + |tn:billTo tn:[subjectAutoincrementId] { + | tn:name [exp.billTo.name] xs:string ; + | tn:street [exp.billTo.street] xs:string ; + | tn:city [exp.billTo.city] xs:string ; + | tn:state [exp.billTo.state] xs:string ; + | tn:zip [exp.billTo.zip] xs:decimal ; + | tn:country tn:[exp.billTo.country] ; + |} + |tn:shipTo tn:[subjectAutoincrementId] { + | tn:name [exp.shipTo.name] xs:string ; + | tn:street [exp.shipTo.street] xs:string ; + | tn:city [exp.shipTo.city] xs:string ; + | tn:state [exp.shipTo.state] xs:string ; + | tn:zip [exp.shipTo.zip] xs:decimal ; + | tn:country tn:[exp.shipTo.country] ; + |}""".stripMargin.replaceAll(" |\n|\t", "")) + } + + + + +} From 3ecb4901e801ea02a2cf718617fb5e655eecd6a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= <herminiogg@hotmail.com> Date: Tue, 27 Oct 2020 13:41:11 +0100 Subject: [PATCH 10/22] Fixed Scala version on Travis CI --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7a2028d..70b47bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,3 @@ language: scala scala: - - 2.11.2 \ No newline at end of file + - 2.12.4 \ No newline at end of file From 189ea56e8f12c96fe2ec50cb60f443edc1aeb9fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= <herminiogg@hotmail.com> Date: Tue, 27 Oct 2020 15:39:55 +0100 Subject: [PATCH 11/22] Added JDK on Travis CI config --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 70b47bf..cbf625a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,6 @@ language: scala + +jdk: openjdk8 + scala: - 2.12.4 \ No newline at end of file From d21b888e4767545543ed18f513df06682e43cfcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= <herminiogg@hotmail.com> Date: Thu, 29 Oct 2020 11:54:14 +0100 Subject: [PATCH 12/22] Changed ShExML dependency version --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 68e05e0..a1173bb 100644 --- a/build.sbt +++ b/build.sbt @@ -10,7 +10,7 @@ resolvers += "jitpack" at "https://jitpack.io" libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % "test" -libraryDependencies += "com.github.herminiogg" % "shexml" % "master-SNAPSHOT" +libraryDependencies += "com.github.herminiogg" % "shexml" % "develop-SNAPSHOT" libraryDependencies += "info.picocli" % "picocli" % "4.0.4" From 045c6d37c7447b4554b7994322bc48cd098cbefc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= <herminiogg@hotmail.com> Date: Thu, 29 Oct 2020 12:53:58 +0100 Subject: [PATCH 13/22] Changes for ShExML new develop version --- .../es/weso/xmlschema2shex/generation/ShExMLPrinter.scala | 4 ++-- .../generation/XMLSchema2ShExMLDeclarationsConverter.scala | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala index 669815a..1ed5faf 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala @@ -1,6 +1,6 @@ package es.weso.xmlschema2shex.generation -import es.weso.shexml.ast.{AutoIncrement, Declaration, Expression, Field, Iterator, IteratorQuery, NestedIterator, ObjectElement, PredicateObject, Prefix, ShExML, Shape, ShapeLink, Source, URL, Var} +import es.weso.shexml.ast.{AutoIncrement, Declaration, Expression, Field, Iterator, IteratorQuery, NestedIterator, ObjectElement, PredicateObject, Prefix, QueryClause, ShExML, Shape, ShapeLink, Source, URL, Var} class ShExMLPrinter { @@ -27,7 +27,7 @@ class ShExMLPrinter { def print(i: Iterator, indentation: Int): String = { val indentationString = generateIndentation(indentation) indentationString + - "ITERATOR " + i.name.name + " <xpath: " + i.queryClause.query + "> {\n" + + "ITERATOR " + i.name.name + " <xpath: " + i.queryClause.asInstanceOf[QueryClause].query + "> {\n" + i.fields.map(print(_, indentation + 1)).mkString("") + i.iterators.map(print(_, indentation + 1)).mkString("") + indentationString + "}\n" diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala index b34ea7b..48dffea 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala @@ -1,6 +1,6 @@ package es.weso.xmlschema2shex.generation -import es.weso.shexml.ast.{AST, Declaration, DeclarationStatement, Expression, Field, FieldQuery, Iterator, IteratorQuery, NestedIterator, Prefix, ShExML, Source, URL, Var, XmlPath} +import es.weso.shexml.ast.{AST, Declaration, DeclarationStatement, Expression, Field, FieldQuery, Iterator, IteratorQuery, NestedIterator, Prefix, QueryClause, ShExML, Source, URL, Var, XmlPath} import es.weso.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, ElementsHolder, Schema, Sequence, SimpleType, Typeable} class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTable: Map[String, Typeable]) extends NameNormalizator { @@ -40,7 +40,7 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl val sequenceResults = convertSequence(c.elementsHolder) val iteratorsFromSequence = sequenceResults.filter(_.isInstanceOf[Iterator]).map(_.asInstanceOf[Iterator]) val nestedIterators = iteratorsFromSequence.map(i => - NestedIterator(i.name, XmlPath(i.queryClause.query.substring(1)), i.fields, i.iterators)) + NestedIterator(i.name, XmlPath(i.queryClause.asInstanceOf[QueryClause].query.substring(1)), i.fields, i.iterators)) val fieldsFromSequence = sequenceResults.filter(_.isInstanceOf[Field]).map(_.asInstanceOf[Field]) val fields = attributeElementsFields ::: fieldsFromSequence val nameOption = if(e.name.isDefined) e.name else e.ref From c088da1c37abdcd8ceb47e88ca24ab1912e09cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= <herminiogg@hotmail.com> Date: Mon, 5 Apr 2021 15:40:55 +0200 Subject: [PATCH 14/22] Changed ShExML version to v0.2.5 --- build.sbt | 4 ++-- .../xmlschema2shex/generation/ShExMLPrinter.scala | 2 +- .../XMLSchema2ShExMLDeclarationsConverter.scala | 6 +++--- .../XMLSchema2ShExMLShapesGeneration.scala | 12 ++++++------ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/build.sbt b/build.sbt index a1173bb..8c59dd0 100644 --- a/build.sbt +++ b/build.sbt @@ -4,13 +4,13 @@ organization := "es.weso" version := "0.1-SNAPSHOT" -scalaVersion := "2.12.4" +scalaVersion := "2.12.8" resolvers += "jitpack" at "https://jitpack.io" libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % "test" -libraryDependencies += "com.github.herminiogg" % "shexml" % "develop-SNAPSHOT" +libraryDependencies += "com.github.herminiogg" % "shexml" % "v0.2.5" libraryDependencies += "info.picocli" % "picocli" % "4.0.4" diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala index 1ed5faf..6b0f7ae 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala @@ -60,7 +60,7 @@ class ShExMLPrinter { def print(po: PredicateObject, indentation: Int): String = { val objectPart = po.objectOrShapeLink match { - case ObjectElement(prefix, action, literalValue, matcher, dataType, langTag) => literalValue match { + case ObjectElement(prefix, action, literalValue, matcher, dataType, langTag, None) => literalValue match { case Some(literal) => prefix + literal + dataType.getOrElse("") case None => { val actionString = if(action.isDefined) action.get.asInstanceOf[Var].name else "" diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala index 48dffea..af9aeef 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala @@ -32,7 +32,7 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl private def generatePlainElement(e: Element): Field = { val name = normalizeName(e.name, e.ref) - Field(Var(name), FieldQuery(name)) + Field(Var(name), FieldQuery(name), false, false) } def convertComplexType(c: ComplexType, e: Element): Iterator = { @@ -51,12 +51,12 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl def convertSimpleType(s: SimpleType, e: Element): Field = { val name = normalizeName(e.name, e.ref) - Field(Var(name), FieldQuery(name)) + Field(Var(name), FieldQuery(name), false, false) } def convertAttributeElement(ae: AttributeElement): Field = { val name = normalizeName(ae.name, ae.ref) - Field(Var(name), FieldQuery(name)) + Field(Var(name), FieldQuery(name), false, false) } def convertSequence(e: ElementsHolder): List[AST] = { diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala index aa950fc..7eaa497 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -1,6 +1,6 @@ package es.weso.xmlschema2shex.generation -import es.weso.shexml.ast.{ExpOrVar, ObjectElement, Predicate, PredicateObject, ShExML, Shape, ShapeLink, ShapeVar, Var} +import es.weso.shexml.ast.{DataTypeLiteral, ExpOrVar, ObjectElement, Predicate, PredicateObject, ShExML, Shape, ShapeLink, ShapeVar, Var} import es.weso.xmlschema2shex.ast._ /** @@ -95,15 +95,15 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator s.restriction match { case Some(restriction) => restriction.base match { case Some(name) => - ObjectElement("", action, None, None, Some(normalizeName(name)), None) - case None => ObjectElement("", action, None, None, s.name, None) + ObjectElement("", action, None, None, Some(DataTypeLiteral(normalizeName(name))), None, None) + case None => ObjectElement("", action, None, None, s.name.map(DataTypeLiteral), None, None) } - case None => ObjectElement("", action, None, None, s.name, None) + case None => ObjectElement("", action, None, None, s.name.map(DataTypeLiteral), None, None) } } case x: XSDType => x match { - case p: XSNMToken => ObjectElement(getDefaultPrefix(), action, None, None, None, None) // that will be pattern but not supported right now in ShExML - case _ => ObjectElement("", action, None, None, Some(x.name), None) + case p: XSNMToken => ObjectElement(getDefaultPrefix(), action, None, None, None, None, None) // that will be pattern but not supported right now in ShExML + case _ => ObjectElement("", action, None, None, Some(DataTypeLiteral(x.name)), None, None) } } } From a4d46deacf45fe291449354b6b1cb872d9664e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garci=CC=81a=20Gonza=CC=81lez?= <herminiogg@hotmail.com> Date: Mon, 5 Apr 2021 16:12:56 +0200 Subject: [PATCH 15/22] Fixed not working tests --- build.sbt | 2 +- .../xmlschema2shex/generation/ShExMLPrinter.scala | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index 8c59dd0..c959462 100644 --- a/build.sbt +++ b/build.sbt @@ -10,7 +10,7 @@ resolvers += "jitpack" at "https://jitpack.io" libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % "test" -libraryDependencies += "com.github.herminiogg" % "shexml" % "v0.2.5" +libraryDependencies += "com.github.herminiogg" % "shexml" % "develop-SNAPSHOT" libraryDependencies += "info.picocli" % "picocli" % "4.0.4" diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala index 6b0f7ae..ac0bbc0 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala @@ -1,6 +1,6 @@ package es.weso.xmlschema2shex.generation -import es.weso.shexml.ast.{AutoIncrement, Declaration, Expression, Field, Iterator, IteratorQuery, NestedIterator, ObjectElement, PredicateObject, Prefix, QueryClause, ShExML, Shape, ShapeLink, Source, URL, Var} +import es.weso.shexml.ast.{AutoIncrement, DataType, DataTypeGeneration, DataTypeLiteral, Declaration, Expression, Field, Iterator, IteratorQuery, NestedIterator, ObjectElement, PredicateObject, Prefix, QueryClause, ShExML, Shape, ShapeLink, Source, URL, Var} class ShExMLPrinter { @@ -61,10 +61,10 @@ class ShExMLPrinter { def print(po: PredicateObject, indentation: Int): String = { val objectPart = po.objectOrShapeLink match { case ObjectElement(prefix, action, literalValue, matcher, dataType, langTag, None) => literalValue match { - case Some(literal) => prefix + literal + dataType.getOrElse("") + case Some(literal) => prefix + literal + printDatatype(dataType) case None => { val actionString = if(action.isDefined) action.get.asInstanceOf[Var].name else "" - prefix + "[" + actionString + "] " + dataType.getOrElse("") + prefix + "[" + actionString + "] " + printDatatype(dataType) } } case ShapeLink(shape) => "@" + shape.name @@ -95,4 +95,9 @@ class ShExMLPrinter { indentationStrings.mkString("") } + private def printDatatype(dt: Option[DataType]): String = dt.map({ + case DataTypeLiteral(value) => value + case DataTypeGeneration(prefix, action, matcher) => "" //to be supported + }).getOrElse("") + } From 5cda06cd69023cd438d8eb443ec5da2022baf306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garc=C3=ADa=20Gonz=C3=A1lez?= <herminiogg@hotmail.com> Date: Tue, 18 Jul 2023 10:48:46 +0200 Subject: [PATCH 16/22] Fixed some dependency problems --- build.sbt | 4 ++-- src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index c959462..770d43f 100644 --- a/build.sbt +++ b/build.sbt @@ -10,7 +10,7 @@ resolvers += "jitpack" at "https://jitpack.io" libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % "test" -libraryDependencies += "com.github.herminiogg" % "shexml" % "develop-SNAPSHOT" +libraryDependencies += "com.github.herminiogg" % "ShExML" % "0.2.5" libraryDependencies += "info.picocli" % "picocli" % "4.0.4" - +mainClass in (Compile, run) := Some("es.weso.xmlschema2shex.Main") \ No newline at end of file diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala index 3454d01..cc11db0 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala +++ b/src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala @@ -43,7 +43,7 @@ class Main extends Callable[Int] { fw.close() } println(result) - 1 + 0 } finally { fileHandler.close() } } From ef8d4063491e9245cd5f24e8cc820bf194ea9bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garc=C3=ADa=20Gonz=C3=A1lez?= <herminiogg@hotmail.com> Date: Thu, 18 Jan 2024 12:09:04 +0100 Subject: [PATCH 17/22] Updating this library to the latest versions and cleaning stuff --- .github/workflows/scala.yml | 18 ++++ .gitignore | 2 + build.sbt | 30 +++---- project/build.properties | 2 +- .../xmlschema2shex/ast/AttributeElement.scala | 5 -- .../weso/xmlschema2shex/parser/Parser.scala | 83 ------------------- .../herminiogarcia}/xmlschema2shex/Main.scala | 7 +- .../xmlschema2shex/ast/Attributes.scala | 2 +- .../xmlschema2shex/ast/ElementsHolder.scala | 2 +- .../xmlschema2shex/ast/Restriction.scala | 2 +- .../ast/RestrictionModifier.scala | 2 +- .../xmlschema2shex/ast/Schema.scala | 2 +- .../xmlschema2shex/ast/Tag.scala | 2 +- .../check/SemanticChecker.scala | 6 +- .../decorator/NameDecorator.scala | 4 +- .../decorator/TypeDecorator.scala | 4 +- .../generation/CodeGenerator.scala | 6 +- .../generation/CodeGeneratorShExML.scala | 6 +- .../generation/NameNormalizator.scala | 4 +- .../generation/ShExMLPrinter.scala | 18 ++-- .../generation/VarTableBuilder.scala | 4 +- ...MLSchema2ShExMLDeclarationsConverter.scala | 6 +- .../XMLSchema2ShExMLShapesGeneration.scala | 20 ++--- .../XMLSchema2ShexCompletionGenerator.scala | 9 +- .../parser/XMLSchema2ShexParser.scala | 12 +-- .../parser/XMLSchemaParser.scala | 19 +++-- .../ShExGenerationTests.scala | 60 +++++++------- .../ShExMLGenerationTests.scala | 44 +++++----- 28 files changed, 162 insertions(+), 219 deletions(-) create mode 100644 .github/workflows/scala.yml delete mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/ast/AttributeElement.scala delete mode 100644 src/main/scala-2.12/es/weso/xmlschema2shex/parser/Parser.scala rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/Main.scala (91%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/ast/Attributes.scala (69%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/ast/ElementsHolder.scala (89%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/ast/Restriction.scala (86%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/ast/RestrictionModifier.scala (94%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/ast/Schema.scala (74%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/ast/Tag.scala (99%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/check/SemanticChecker.scala (84%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/decorator/NameDecorator.scala (93%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/decorator/TypeDecorator.scala (90%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/generation/CodeGenerator.scala (94%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/generation/CodeGeneratorShExML.scala (94%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/generation/NameNormalizator.scala (84%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/generation/ShExMLPrinter.scala (81%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/generation/VarTableBuilder.scala (79%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala (87%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala (85%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala (77%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/parser/XMLSchema2ShexParser.scala (73%) rename src/main/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/parser/XMLSchemaParser.scala (85%) rename src/test/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala (68%) rename src/test/{scala-2.12/es/weso => scala/com/herminiogarcia}/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala (91%) diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml new file mode 100644 index 0000000..922e310 --- /dev/null +++ b/.github/workflows/scala.yml @@ -0,0 +1,18 @@ +name: Scala CI + +on: push + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 8 + uses: actions/setup-java@v2 + with: + java-version: '8' + distribution: 'adopt' + - name: Run tests + run: sbt "+ test" diff --git a/.gitignore b/.gitignore index 1ad9613..93364c1 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ project/plugins/project/ .scala_dependencies .worksheet .idea/ + +.bsp diff --git a/build.sbt b/build.sbt index 770d43f..26675b1 100644 --- a/build.sbt +++ b/build.sbt @@ -1,16 +1,16 @@ -name := "xmlschema2shex" +ThisBuild / organization := "com.herminiogarcia" -organization := "es.weso" - -version := "0.1-SNAPSHOT" - -scalaVersion := "2.12.8" - -resolvers += "jitpack" at "https://jitpack.io" - -libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" -libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" % "test" -libraryDependencies += "com.github.herminiogg" % "ShExML" % "0.2.5" -libraryDependencies += "info.picocli" % "picocli" % "4.0.4" - -mainClass in (Compile, run) := Some("es.weso.xmlschema2shex.Main") \ No newline at end of file +lazy val xmlschema2shex = project + .in(file(".")) + .settings( + name := "xmlschema2shex", + version := "0.1.0", + scalaVersion := "3.2.0", + crossScalaVersions := Seq("2.12.17", "2.13.9", "3.2.0"), + libraryDependencies ++= Seq( + "org.scala-lang.modules" %% "scala-parser-combinators" % "2.3.0", + "org.scalatest" %% "scalatest" % "3.2.15" % "test", + "com.herminiogarcia" %% "shexml" % "0.4.2" exclude("io.gatling", "gatling-jsonpath"), + "info.picocli" % "picocli" % "4.7.3", + ) + ) \ No newline at end of file diff --git a/project/build.properties b/project/build.properties index d638b4f..ff6e0dd 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version = 0.13.8 \ No newline at end of file +sbt.version = 1.7.2 \ No newline at end of file diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/AttributeElement.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/ast/AttributeElement.scala deleted file mode 100644 index 415446e..0000000 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/AttributeElement.scala +++ /dev/null @@ -1,5 +0,0 @@ -package es.weso.xmlschema2shex.ast - -/** - * Created by herminio on 4/10/16. - */ diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/Parser.scala b/src/main/scala-2.12/es/weso/xmlschema2shex/parser/Parser.scala deleted file mode 100644 index ad5baa3..0000000 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/Parser.scala +++ /dev/null @@ -1,83 +0,0 @@ -package es.weso.xmlschema2shex.parser - -import java.io.FileWriter - -import es.weso.xmlschema2shex.check.SemanticChecker -import es.weso.xmlschema2shex.decorator.{NameDecorator, TypeDecorator} -import es.weso.xmlschema2shex.generation.CodeGenerator - -/** - * Created by herminio on 4/10/16. - */ -object Parser extends XMLSchemaParser{ - def main(args: Array[String]): Unit = { - val xml = """<?xml version="1.0"?> - |<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> - |<xs:attribute name="id" type="xs:positiveInteger"/> - |<xs:complexType name="station"> - | <xs:sequence> - | <xs:element name="name" type="xs:string" /> - | </xs:sequence> - | <xs:attribute ref="id" use="required"/> - |</xs:complexType> - |<xs:complexType name="driver"> - | <xs:sequence> - | <xs:element name="name" type="xs:string" /> - | <xs:element name="birth_date" type="xs:date" /> - | <xs:element name="email" type="xs:string" /> - | <xs:element name="phone" type="xs:string" /> - | <xs:element name="avatar" type="xs:string" /> - | </xs:sequence> - | <xs:attribute ref="id" use="required"/> - |</xs:complexType> - |<xs:element name="lvb_system"> - | <xs:complexType> - | <xs:sequence> - | <xs:element name="line" minOccurs="0" maxOccurs="unbounded" > - | <xs:complexType> - | <xs:sequence> - | <xs:element name="code" type="xs:string" /> - | <xs:element name="type" type="xs:string" /> - | <xs:element name="start_time_operation" type="xs:time" /> - | <xs:element name="end_time_operation" type="xs:time" /> - | <xs:element name="count_vehicles"> - | <xs:simpleType> - | <xs:restriction base="xs:integer"> - | <xs:minInclusive value="0"/> - | <xs:maxInclusive value="10"/> - | </xs:restriction> - | </xs:simpleType> - | </xs:element> - | <xs:element name="map" type="xs:string" /> - | <xs:element name="start_station" type="station" minOccurs="0" maxOccurs="1" /> - | <xs:element name="end_station" type="station" minOccurs="0" maxOccurs="1" /> - | <xs:element name="intermediate_stations" type="station" minOccurs="0" maxOccurs="5" /> - | <xs:element name="vehicles_line" minOccurs="0" maxOccurs="10" > - | <xs:complexType> - | <xs:sequence> - | <xs:element name="name" type="xs:string" /> - | <xs:element name="capacity" type="xs:integer" /> - | <xs:element name="driver" minOccurs="0" maxOccurs="unbounded" type='driver' /> - | </xs:sequence> - | <xs:attribute ref="id" use="required"/> - | </xs:complexType> - | </xs:element> - | </xs:sequence> - | <xs:attribute ref="id" use="required"/> - | </xs:complexType> - | </xs:element> - | </xs:sequence> - | </xs:complexType> - |</xs:element> - |</xs:schema>""".stripMargin - - /**val output = XMLSchema2ShexParser().parse(xml, None) - val fw = new FileWriter("result.shex")*/ - val output = XMLSchema2ShexParser().convertToShExML(xml) - val fw = new FileWriter("result.shexml") - fw.write(output) - fw.close() - println(output) - } - -} \ No newline at end of file diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala similarity index 91% rename from src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala index cc11db0..8de388c 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/Main.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala @@ -1,9 +1,8 @@ -package es.weso.xmlschema2shex +package com.herminiogarcia.xmlschema2shex +import com.herminiogarcia.xmlschema2shex.parser.XMLSchema2ShexParser import java.io.FileWriter import java.util.concurrent.Callable - -import es.weso.xmlschema2shex.parser.XMLSchema2ShexParser import picocli.CommandLine import picocli.CommandLine.{Command, Option} @@ -43,7 +42,7 @@ class Main extends Callable[Int] { fw.close() } println(result) - 0 + 1 } finally { fileHandler.close() } } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Attributes.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Attributes.scala similarity index 69% rename from src/main/scala-2.12/es/weso/xmlschema2shex/ast/Attributes.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Attributes.scala index 9fe95dc..5cf6ef5 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Attributes.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Attributes.scala @@ -1,4 +1,4 @@ -package es.weso.xmlschema2shex.ast +package com.herminiogarcia.xmlschema2shex.ast /** * Created by herminio on 4/10/16. diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/ElementsHolder.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/ElementsHolder.scala similarity index 89% rename from src/main/scala-2.12/es/weso/xmlschema2shex/ast/ElementsHolder.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/ast/ElementsHolder.scala index 80dfed7..ae75d88 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/ElementsHolder.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/ElementsHolder.scala @@ -1,4 +1,4 @@ -package es.weso.xmlschema2shex.ast +package com.herminiogarcia.xmlschema2shex.ast /** * Created by herminio on 4/10/16. diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Restriction.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Restriction.scala similarity index 86% rename from src/main/scala-2.12/es/weso/xmlschema2shex/ast/Restriction.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Restriction.scala index 8469d36..3a6cea9 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Restriction.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Restriction.scala @@ -1,4 +1,4 @@ -package es.weso.xmlschema2shex.ast +package com.herminiogarcia.xmlschema2shex.ast /** * Created by herminio on 4/10/16. diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/RestrictionModifier.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/RestrictionModifier.scala similarity index 94% rename from src/main/scala-2.12/es/weso/xmlschema2shex/ast/RestrictionModifier.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/ast/RestrictionModifier.scala index 058c0bc..62b3895 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/RestrictionModifier.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/RestrictionModifier.scala @@ -1,4 +1,4 @@ -package es.weso.xmlschema2shex.ast +package com.herminiogarcia.xmlschema2shex.ast /** * Created by herminio on 4/10/16. diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Schema.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Schema.scala similarity index 74% rename from src/main/scala-2.12/es/weso/xmlschema2shex/ast/Schema.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Schema.scala index 46d3c37..3380a26 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Schema.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Schema.scala @@ -1,4 +1,4 @@ -package es.weso.xmlschema2shex.ast +package com.herminiogarcia.xmlschema2shex.ast /** * Created by herminio on 4/10/16. diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Tag.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Tag.scala similarity index 99% rename from src/main/scala-2.12/es/weso/xmlschema2shex/ast/Tag.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Tag.scala index 60a30c5..6ad4e4f 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/ast/Tag.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/ast/Tag.scala @@ -1,4 +1,4 @@ -package es.weso.xmlschema2shex.ast +package com.herminiogarcia.xmlschema2shex.ast /** * Created by herminio on 4/10/16. diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/check/SemanticChecker.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/check/SemanticChecker.scala similarity index 84% rename from src/main/scala-2.12/es/weso/xmlschema2shex/check/SemanticChecker.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/check/SemanticChecker.scala index b37782f..d9c8251 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/check/SemanticChecker.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/check/SemanticChecker.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.check +package com.herminiogarcia.xmlschema2shex.check -import es.weso.xmlschema2shex.ast._ +import com.herminiogarcia.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, Restriction, Schema, SimpleType, Tag, Type, Typeable} /** * Created by herminio on 5/10/16. @@ -44,7 +44,7 @@ class SemanticChecker(val schema: Schema) { } def checkRestriction(restriction: Restriction): Unit = { - restriction.restrictions.foreach(println(_)) + //restriction.restrictions.foreach(println(_)) } } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/NameDecorator.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/decorator/NameDecorator.scala similarity index 93% rename from src/main/scala-2.12/es/weso/xmlschema2shex/decorator/NameDecorator.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/decorator/NameDecorator.scala index 12bf826..4f40ad6 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/NameDecorator.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/decorator/NameDecorator.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.decorator +package com.herminiogarcia.xmlschema2shex.decorator -import es.weso.xmlschema2shex.ast.{ComplexType, Schema, Element} +import com.herminiogarcia.xmlschema2shex.ast.{ComplexType, Schema} /** * Created by herminio on 6/10/16. diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/TypeDecorator.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/decorator/TypeDecorator.scala similarity index 90% rename from src/main/scala-2.12/es/weso/xmlschema2shex/decorator/TypeDecorator.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/decorator/TypeDecorator.scala index 5218f6a..e722dc8 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/decorator/TypeDecorator.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/decorator/TypeDecorator.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.decorator +package com.herminiogarcia.xmlschema2shex.decorator -import es.weso.xmlschema2shex.ast._ +import com.herminiogarcia.xmlschema2shex.ast.{AttributeElement, Attributes, ComplexType, Element, Schema, SimpleType, Tag, Type, Typeable, XSDAnyURI, XSDBase64Binary, XSDBoolean, XSDByte, XSDDate, XSDDateTime, XSDDecimal, XSDDouble, XSDDuration, XSDENTITY, XSDGDay, XSDGMonth, XSDGMonthDay, XSDGYear, XSDGYearMonth, XSDHexBinary, XSDID, XSDIDREF, XSDIDREFS, XSDInt, XSDInteger, XSDLong, XSDNCName, XSDNMTokens, XSDName, XSDNegativeInteger, XSDNonPositiveInteger, XSDNotation, XSDPositiveInteger, XSDQName, XSDShort, XSDString, XSDTime, XSDType, XSDUnsignedByte, XSDUnsignedInt, XSDUnsignedLong, XSDUnsignedShort, XSNMToken} /** * Created by herminio on 6/10/16. diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGenerator.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/CodeGenerator.scala similarity index 94% rename from src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGenerator.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/generation/CodeGenerator.scala index 0ad7b0d..862e7cf 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGenerator.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/CodeGenerator.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.generation +package com.herminiogarcia.xmlschema2shex.generation -import es.weso.xmlschema2shex.ast._ +import com.herminiogarcia.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, ElementsHolder, Schema, SimpleType, Typeable, XSDType, XSNMToken} /** * Created by herminio on 5/10/16. @@ -70,7 +70,7 @@ class CodeGenerator(schema: Schema) { case Some(theName) => ":" + theName case None => element.ref match { case Some(ref) => ":" + ref - case None => None + case None => "" } } val typeString = element.aType match { diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/CodeGeneratorShExML.scala similarity index 94% rename from src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/generation/CodeGeneratorShExML.scala index 478a06a..b292b40 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/CodeGeneratorShExML.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/CodeGeneratorShExML.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.generation +package com.herminiogarcia.xmlschema2shex.generation -import es.weso.xmlschema2shex.ast._ +import com.herminiogarcia.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, ElementsHolder, Schema, SimpleType, Typeable, XSDType, XSNMToken} /** * Created by herminio on 5/10/16. @@ -70,7 +70,7 @@ class CodeGeneratorShExML(schema: Schema) { case Some(theName) => "FIELD " + theName + " <"+ theName +">" case None => element.ref match { case Some(ref) => ":" + ref - case None => None + case None => "" } } val typeString = element.aType match { diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/NameNormalizator.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/NameNormalizator.scala similarity index 84% rename from src/main/scala-2.12/es/weso/xmlschema2shex/generation/NameNormalizator.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/generation/NameNormalizator.scala index c14fa7d..d982863 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/NameNormalizator.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/NameNormalizator.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.generation +package com.herminiogarcia.xmlschema2shex.generation -import es.weso.xmlschema2shex.ast.Typeable +import com.herminiogarcia.xmlschema2shex.ast.Typeable trait NameNormalizator { diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/ShExMLPrinter.scala similarity index 81% rename from src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/generation/ShExMLPrinter.scala index ac0bbc0..a653efa 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/ShExMLPrinter.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/ShExMLPrinter.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.generation +package com.herminiogarcia.xmlschema2shex.generation -import es.weso.shexml.ast.{AutoIncrement, DataType, DataTypeGeneration, DataTypeLiteral, Declaration, Expression, Field, Iterator, IteratorQuery, NestedIterator, ObjectElement, PredicateObject, Prefix, QueryClause, ShExML, Shape, ShapeLink, Source, URL, Var} +import com.herminiogarcia.shexml.ast.{Action, AutoIncrement, DataType, DataTypeGeneration, DataTypeLiteral, Declaration, Expression, Field, Iterator, IteratorQuery, LiteralSubject, NestedIterator, ObjectElement, PredicateObject, Prefix, QueryClause, ShExML, Shape, ShapeLink, ShapeVar, Source, URL, Var} class ShExMLPrinter { @@ -49,18 +49,26 @@ class ShExMLPrinter { def print(s: Shape, indentation: Int): String = { val shapeAction = s.action match { - case Var(action) => action + case Action(_, action, _) => action match { + case Var(name) => name + case _ => throw new Exception("Not supported") + } + case LiteralSubject(_, value) => value case _ => "" } + val shapePrefix = s.action match { + case Action(shapePrefix, _, _) => shapePrefix + case LiteralSubject(prefix, _) => prefix.name + } generateIndentation(indentation) + - s.shapeName.name + " " + s.shapePrefix + "[" + shapeAction + "] {\n" + + s.shapeName.name + " " + shapePrefix + "[" + shapeAction + "] {\n" + s.predicateObjects.map(po => print(po, indentation + 1)).mkString("") + "}\n" } def print(po: PredicateObject, indentation: Int): String = { val objectPart = po.objectOrShapeLink match { - case ObjectElement(prefix, action, literalValue, matcher, dataType, langTag, None) => literalValue match { + case ObjectElement(prefix, action, literalValue, matcher, None, dataType, langTag, None) => literalValue match { case Some(literal) => prefix + literal + printDatatype(dataType) case None => { val actionString = if(action.isDefined) action.get.asInstanceOf[Var].name else "" diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/VarTableBuilder.scala similarity index 79% rename from src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/generation/VarTableBuilder.scala index 617292d..b41e5d4 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/VarTableBuilder.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/VarTableBuilder.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.generation +package com.herminiogarcia.xmlschema2shex.generation -import es.weso.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, Schema, SimpleType, Tag, Typeable} +import com.herminiogarcia.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, Schema, SimpleType, Tag, Typeable} import scala.collection.mutable diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala similarity index 87% rename from src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala index af9aeef..621b9c5 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala @@ -1,7 +1,7 @@ -package es.weso.xmlschema2shex.generation +package com.herminiogarcia.xmlschema2shex.generation -import es.weso.shexml.ast.{AST, Declaration, DeclarationStatement, Expression, Field, FieldQuery, Iterator, IteratorQuery, NestedIterator, Prefix, QueryClause, ShExML, Source, URL, Var, XmlPath} -import es.weso.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, ElementsHolder, Schema, Sequence, SimpleType, Typeable} +import com.herminiogarcia.shexml.ast.{AST, Declaration, DeclarationStatement, Expression, Field, FieldQuery, Iterator, IteratorQuery, NestedIterator, Prefix, QueryClause, ShExML, Source, URL, Var, XmlPath} +import com.herminiogarcia.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, ElementsHolder, Schema, Sequence, SimpleType, Typeable} class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTable: Map[String, Typeable]) extends NameNormalizator { diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala similarity index 85% rename from src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala index 7eaa497..d803417 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLShapesGeneration.scala @@ -1,7 +1,7 @@ -package es.weso.xmlschema2shex.generation +package com.herminiogarcia.xmlschema2shex.generation -import es.weso.shexml.ast.{DataTypeLiteral, ExpOrVar, ObjectElement, Predicate, PredicateObject, ShExML, Shape, ShapeLink, ShapeVar, Var} -import es.weso.xmlschema2shex.ast._ +import com.herminiogarcia.shexml.ast.{Action, DataTypeLiteral, ExpOrVar, ObjectElement, Predicate, PredicateObject, ShExML, Shape, ShapeLink, ShapeVar, Var} +import com.herminiogarcia.xmlschema2shex.ast.{AttributeElement, ComplexType, Element, ElementsHolder, Schema, SimpleType, Typeable, XSDType, XSNMToken} /** * Created by herminio on 5/10/16. @@ -42,9 +42,9 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator && po.objectOrShapeLink.isInstanceOf[ObjectElement]) match { case Some(id) => id.objectOrShapeLink.asInstanceOf[ObjectElement].action.orNull case None => Var("subjectAutoincrementId") - } - val shape = Shape(shapeVar, prefix, action, predicateObjects, None) + val actionObject = Action(prefix, action, None) + val shape = Shape(shapeVar, actionObject, predicateObjects, None) for(element <- complexType.elementsHolder.elements) yield element.aType match { case Some(nestedType) => nestedType match { @@ -95,15 +95,15 @@ class XMLSchema2ShExMLShapesGeneration(schema: Schema) extends NameNormalizator s.restriction match { case Some(restriction) => restriction.base match { case Some(name) => - ObjectElement("", action, None, None, Some(DataTypeLiteral(normalizeName(name))), None, None) - case None => ObjectElement("", action, None, None, s.name.map(DataTypeLiteral), None, None) + ObjectElement("", action, None, None, None, Some(DataTypeLiteral(normalizeName(name))), None, None) + case None => ObjectElement("", action, None, None, None, s.name.map(DataTypeLiteral.apply), None, None) } - case None => ObjectElement("", action, None, None, s.name.map(DataTypeLiteral), None, None) + case None => ObjectElement("", action, None, None, None, s.name.map(DataTypeLiteral.apply), None, None) } } case x: XSDType => x match { - case p: XSNMToken => ObjectElement(getDefaultPrefix(), action, None, None, None, None, None) // that will be pattern but not supported right now in ShExML - case _ => ObjectElement("", action, None, None, Some(DataTypeLiteral(x.name)), None, None) + case p: XSNMToken => ObjectElement(getDefaultPrefix(), action, None, None, None, None, None, None) // that will be pattern but not supported right now in ShExML + case _ => ObjectElement("", action, None, None, None, Some(DataTypeLiteral(x.name)), None, None) } } } diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala similarity index 77% rename from src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala index 797cdce..a1b6963 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.generation +package com.herminiogarcia.xmlschema2shex.generation -import es.weso.shexml.ast.{AutoIncrement, Declaration, Prefix, Shape, URL, Var} +import com.herminiogarcia.shexml.ast.{Action, AutoIncrement, Declaration, Prefix, Shape, URL, Var} class XMLSchema2ShexCompletionGenerator(declarations: List[Declaration], shapes: List[Shape]) { @@ -23,7 +23,10 @@ class XMLSchema2ShexCompletionGenerator(declarations: List[Declaration], shapes: def completeAutoincrement(): Option[Declaration] = { val needForAutoincrementDeclaration = shapes.exists(s => s.action match { - case Var(name) => name == "subjectAutoincrementId" + case Action(_, action, _) => action match { + case Var(name) => name == "subjectAutoincrementId" + case _ => false + } case _ => false }) if(needForAutoincrementDeclaration) { diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchema2ShexParser.scala similarity index 73% rename from src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchema2ShexParser.scala index 0e08d75..907f132 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchema2ShexParser.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchema2ShexParser.scala @@ -1,10 +1,10 @@ -package es.weso.xmlschema2shex.parser +package com.herminiogarcia.xmlschema2shex.parser -import es.weso.shexml.ast.ShExML -import es.weso.xmlschema2shex.ast.Typeable -import es.weso.xmlschema2shex.check.SemanticChecker -import es.weso.xmlschema2shex.decorator.{NameDecorator, TypeDecorator} -import es.weso.xmlschema2shex.generation.{CodeGenerator, CodeGeneratorShExML, ShExMLPrinter, VarTableBuilder, XMLSchema2ShExMLDeclarationsConverter, XMLSchema2ShExMLShapesGeneration, XMLSchema2ShexCompletionGenerator} +import com.herminiogarcia.shexml.ast.ShExML +import com.herminiogarcia.xmlschema2shex.ast.Typeable +import com.herminiogarcia.xmlschema2shex.check.SemanticChecker +import com.herminiogarcia.xmlschema2shex.decorator.{NameDecorator, TypeDecorator} +import com.herminiogarcia.xmlschema2shex.generation.{CodeGenerator, CodeGeneratorShExML, ShExMLPrinter, VarTableBuilder, XMLSchema2ShExMLDeclarationsConverter, XMLSchema2ShExMLShapesGeneration, XMLSchema2ShexCompletionGenerator} import scala.collection.mutable diff --git a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchemaParser.scala similarity index 85% rename from src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala rename to src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchemaParser.scala index d1ef431..1c7a063 100644 --- a/src/main/scala-2.12/es/weso/xmlschema2shex/parser/XMLSchemaParser.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchemaParser.scala @@ -1,16 +1,17 @@ -package es.weso.xmlschema2shex.parser +package com.herminiogarcia.xmlschema2shex.parser /** * Created by herminio on 4/10/16. */ -import es.weso.xmlschema2shex.ast._ +import com.herminiogarcia.xmlschema2shex.ast +import com.herminiogarcia.xmlschema2shex.ast.{All, AttributeElement, Attributes, ComplexType, Element, ElementsHolder, Enumeration, MaxExclusive, MaxInclusive, MinExclusive, MinInclusive, Pattern, Restriction, RestrictionModifier, Schema, Sequence, SimpleType, Tag} import scala.util.parsing.combinator._ class XMLSchemaParser extends JavaTokenParsers { def root: Parser[Schema] = opt("<?xml"~attributes~"?>")~openingTag("schema")~attributes~">"~rep(tags)~closingTag("schema") ^^ { - case _ ~ _ ~ attributes ~ _ ~ tags ~ _ => Schema(attributes, tags) + case _ ~ _ ~ attributes ~ _ ~ tags ~ _ => ast.Schema(attributes, tags) } def tags: Parser[Tag] = element | complexType | simpleType | attribute @@ -82,27 +83,27 @@ class XMLSchemaParser extends JavaTokenParsers { maxInclusiveRestriction | minInclusiveRestriction | patternRestriction | enumeration def maxExclusiveRestriction: Parser[MaxExclusive] = openingTag("maxExclusive")~attributes~"/>" ^^ { - case _ ~ attributes ~ _ => MaxExclusive(attributes) + case _ ~ attributes ~ _ => ast.MaxExclusive(attributes) } def minExclusiveRestriction: Parser[MinExclusive] = openingTag("minExclusive")~attributes~"/>" ^^ { - case _ ~ attributes ~ _ => MinExclusive(attributes) + case _ ~ attributes ~ _ => ast.MinExclusive(attributes) } def maxInclusiveRestriction: Parser[MaxInclusive] = openingTag("maxInclusive")~attributes~"/>" ^^ { - case _ ~ attributes ~ _ => MaxInclusive(attributes) + case _ ~ attributes ~ _ => ast.MaxInclusive(attributes) } def minInclusiveRestriction: Parser[MinInclusive] = openingTag("minInclusive")~attributes~"/>" ^^ { - case _ ~ attributes ~ _ => MinInclusive(attributes) + case _ ~ attributes ~ _ => ast.MinInclusive(attributes) } def patternRestriction: Parser[Pattern] = openingTag("pattern")~attributes~"/>" ^^ { - case _ ~ attributes ~ _ => Pattern(attributes) + case _ ~ attributes ~ _ => ast.Pattern(attributes) } def enumeration: Parser[Enumeration] = openingTag("enumeration")~attributes~"/>" ^^ { - case _ ~ attributes ~ _ => Enumeration(attributes) + case _ ~ attributes ~ _ => ast.Enumeration(attributes) } def annotation: Parser[Any] = openingTag("annotation")~"".r~closingTag("annotation") diff --git a/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala b/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala similarity index 68% rename from src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala rename to src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala index 869b7a4..ecf9505 100644 --- a/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala +++ b/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExGenerationTests.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.inputoutputtests +package com.herminiogarcia.xmlschema2shex.inputoutputtests -import es.weso.xmlschema2shex.parser.XMLSchema2ShexParser +import com.herminiogarcia.xmlschema2shex.parser.XMLSchema2ShexParser import org.scalatest.funsuite.AnyFunSuite import org.scalatest.matchers.should.Matchers @@ -13,93 +13,93 @@ class ShExGenerationTests extends AnyFunSuite with Matchers { test("XML Schema conversion from Microsoft example") { val xml = Source.fromResource("purchaseOrderFull.xsd").mkString - val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") - output should include ("""<PurchaseOrderType> { + val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll("\\s", "") + assert(output.contains("""<PurchaseOrderType> { |:shipTo @<USAddress> {1} ; |:billTo @<USAddress> {1} ; |:comment xs:string ? ; |:items @<Items> {1} ; |:orderDate xs:date {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include ("""<USAddress> { + |}""".stripMargin.replaceAll("\\s", ""))) + assert(output.contains("""<USAddress> { |:name xs:string {1} ; |:street xs:string {1} ; |:city xs:string {1} ; |:state xs:string {1} ; |:zip xs:decimal {1} ; |:country [US] {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include ("""<Items> { + |}""".stripMargin.replaceAll("\\s", ""))) + assert(output.contains("""<Items> { |:item @<item> * ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include ("""<item> { + |}""".stripMargin.replaceAll("\\s", ""))) + assert(output.contains("""<item> { |:productName xs:string {1} ; |:quantity xs:positiveInteger {1, 99} ; |:USPrice xs:decimal {1} ; |:comment xs:string ? ; |:shipDate xs:date ? ; |:partNum xs:string {1} PATTERN \\d{3}-[A-Z]{2} ; - |}""".stripMargin.replaceAll(" |\n", "")) + |}""".stripMargin.replaceAll("\\s", ""))) } test("XML Schema conversion for addresses") { val xml = Source.fromResource("address.xsd").mkString - val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") - output should include("""<addresses> { + val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll("\\s", "") + assert(output.contains("""<addresses> { |:address @<address> + ; - |}""".stripMargin.replaceAll(" |\n", "")) + |}""".stripMargin.replaceAll("\\s", ""))) - output should include("""<address> { + assert(output.contains("""<address> { |:name xs:string ? ; |:street xs:string ? ; - |}""".stripMargin.replaceAll(" |\n", "")) + |}""".stripMargin.replaceAll("\\s", ""))) } test("""Xml1 version""") { val xml = Source.fromResource("xml1version.xsd").mkString - val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") - output should include("""<shiporder> { + val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll("\\s", "") + assert(output.contains("""<shiporder> { |:orderperson xs:string {1} ; |:shipto @<shipto> {1} ; |:item @<item> + ; |:orderid xs:string {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include("""<item> { + |}""".stripMargin.replaceAll("\\s", ""))) + assert(output.contains("""<item> { |:title xs:string {1} ; |:note xs:string ? ; |:quantity xs:positiveInteger {1} ; |:price xs:decimal {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include("""<shipto> { + |}""".stripMargin.replaceAll("\\s", ""))) + assert(output.contains("""<shipto> { |:name xs:string {1} ; |:address xs:string {1} ; |:city xs:string {1} ; |:country xs:string {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) + |}""".stripMargin.replaceAll("\\s", ""))) } test("""Xml2 version""") { val xml = Source.fromResource("xml2version.xsd").mkString - val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll(" |\n", "") - output should include("""<shipordertype> { + val output = XMLSchema2ShexParser().parse(xml, None).stripMargin.replaceAll("\\s", "") + assert(output.contains("""<shipordertype> { |:orderperson xs:string {1} ; |:shipto @<shiptotype> {1} ; |:item @<itemtype> + ; |:orderid xs:string {1} PATTERN [0-9]{6} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include("""<itemtype> { + |}""".stripMargin.replaceAll("\\s", ""))) + assert(output.contains("""<itemtype> { |:title xs:string {1} ; |:note xs:string ? ; |:quantity xs:positiveInteger {1} ; |:price xs:decimal {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) - output should include("""<shiptotype> { + |}""".stripMargin.replaceAll("\\s", ""))) + assert(output.contains("""<shiptotype> { |:name xs:string {1} ; |:address xs:string {1} ; |:city xs:string {1} ; |:country xs:string {1} ; - |}""".stripMargin.replaceAll(" |\n", "")) + |}""".stripMargin.replaceAll("\\s", ""))) } diff --git a/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala b/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala similarity index 91% rename from src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala rename to src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala index 9455d9c..81b2dff 100644 --- a/src/test/scala-2.12/es/weso/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala +++ b/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala @@ -1,6 +1,6 @@ -package es.weso.xmlschema2shex.inputoutputtests +package com.herminiogarcia.xmlschema2shex.inputoutputtests -import es.weso.xmlschema2shex.parser.XMLSchema2ShexParser +import com.herminiogarcia.xmlschema2shex.parser.XMLSchema2ShexParser import org.scalatest.funsuite.AnyFunSuite import org.scalatest.matchers.should.Matchers @@ -13,13 +13,13 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { test("Xml1 version") { val xml = Source.fromResource("xml1version.xsd").mkString - val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll(" |\n|\t", "") + val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll("\\s", "") output should include ("""PREFIX : <http://example.org> |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> - |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll(" |\n|\t", "")) + |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll("\\s", "")) output should include (""" |SOURCE example <http://example.com/example.xml> - |""".stripMargin.replaceAll(" |\n|\t", "")) + |""".stripMargin.replaceAll("\\s", "")) output should include ("""ITERATOR shipto <xpath: /shipto> { | FIELD name <name> | FIELD address <address> @@ -49,7 +49,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | } |} |EXPRESSION exp <example.shipto> - |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll(" |\n|\t", "")) + |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll("\\s", "")) output should include (""":shiporder :[exp.orderid] { | :orderperson [exp.orderperson] xs:string ; | :shipto @:shipto ; @@ -67,18 +67,18 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | :address [exp.shipto.address] xs:string ; | :city [exp.shipto.city] xs:string ; | :country [exp.shipto.country] xs:string ; - |}""".stripMargin.replaceAll(" |\n|\t", "")) + |}""".stripMargin.replaceAll("\\s", "")) } test("""Xml2 version""") { val xml = Source.fromResource("xml2version.xsd").mkString - val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll(" |\n|\t", "") + val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll("\\s", "") output should include ("""PREFIX : <http://example.org> |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> - |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll(" |\n|\t", "")) + |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll("\\s", "")) output should include (""" |SOURCE example <http://example.com/example.xml> - |""".stripMargin.replaceAll(" |\n|\t", "")) + |""".stripMargin.replaceAll("\\s", "")) output should include ("""ITERATOR shiporder <xpath: /shiporder> { | FIELD orderid <orderid> | FIELD orderperson <orderperson> @@ -96,7 +96,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | } |} |EXPRESSION exp <example.shiporder> - |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll(" |\n|\t", "")) + |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll("\\s", "")) output should include (""":shiporder :[exp.orderid] { | :orderperson [exp.orderperson] xs:string ; | :shipto @:shipto ; @@ -114,18 +114,18 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | :address [exp.shipto.address] xs:string ; | :city [exp.shipto.city] xs:string ; | :country [exp.shipto.country] xs:string ; - |}""".stripMargin.replaceAll(" |\n|\t", "")) + |}""".stripMargin.replaceAll("\\s", "")) } test("XML Schema conversion for addresses") { val xml = Source.fromResource("address.xsd").mkString - val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll(" |\n|\t", "") + val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll("\\s", "") output should include ("""PREFIX : <http://example.org> |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> - |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll(" |\n|\t", "")) + |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll("\\s", "")) output should include (""" |SOURCE example <http://example.com/example.xml> - |""".stripMargin.replaceAll(" |\n|\t", "")) + |""".stripMargin.replaceAll("\\s", "")) output should include ("""ITERATOR addresses <xpath: /addresses> { | ITERATOR address <address> { | FIELD name <name> @@ -137,26 +137,26 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | FIELD street <street> |} |EXPRESSION exp <example.addresses> - |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll(" |\n|\t", "")) + |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll("\\s", "")) output should include (""":addresses :[subjectAutoincrementId] { | :address @:address ; |} |:address :[subjectAutoincrementId] { | :name [exp.name] xs:string ; | :street [exp.street] xs:string ; - |}""".stripMargin.replaceAll(" |\n|\t", "")) + |}""".stripMargin.replaceAll("\\s", "")) } test("""XML Schema conversion from Microsoft example""") { val xml = Source.fromResource("purchaseOrderFull.xsd").mkString - val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll(" |\n|\t", "") + val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll("\\s", "") output should include ("""PREFIX : <http://example.org> |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> - |PREFIX tn: <http://tempuri.org/po.xsd>""".stripMargin.replaceAll(" |\n|\t", "")) + |PREFIX tn: <http://tempuri.org/po.xsd>""".stripMargin.replaceAll("\\s", "")) output should include (""" |SOURCE example <http://example.com/example.xml> - |""".stripMargin.replaceAll(" |\n|\t", "")) + |""".stripMargin.replaceAll("\\s", "")) output should include ("""ITERATOR purchaseOrder <xpath: /purchaseOrder> { | FIELD orderDate <orderDate> | FIELD comment <comment> @@ -188,7 +188,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | } |} |EXPRESSION exp <example.purchaseOrder> - |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll(" |\n|\t", "")) + |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll("\\s", "")) output should include ("""tn:purchaseOrder tn:[subjectAutoincrementId] { | tn:shipTo @tn:shipTo ; | tn:billTo @tn:billTo ; @@ -222,7 +222,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | tn:state [exp.shipTo.state] xs:string ; | tn:zip [exp.shipTo.zip] xs:decimal ; | tn:country tn:[exp.shipTo.country] ; - |}""".stripMargin.replaceAll(" |\n|\t", "")) + |}""".stripMargin.replaceAll("\\s", "")) } From d48ffbfc95ab4e7c0ab95a20fa2db5a88b522c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garc=C3=ADa=20Gonz=C3=A1lez?= <herminiogg@hotmail.com> Date: Thu, 18 Jan 2024 13:56:21 +0100 Subject: [PATCH 18/22] Fixed a problem with attributes generation and predicate objects ordering in ShExML generation --- .../generation/ShExMLPrinter.scala | 12 +++++++-- ...MLSchema2ShExMLDeclarationsConverter.scala | 2 +- .../ShExMLGenerationTests.scala | 26 +++++++++---------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/ShExMLPrinter.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/ShExMLPrinter.scala index a653efa..24981c5 100644 --- a/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/ShExMLPrinter.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/ShExMLPrinter.scala @@ -1,6 +1,6 @@ package com.herminiogarcia.xmlschema2shex.generation -import com.herminiogarcia.shexml.ast.{Action, AutoIncrement, DataType, DataTypeGeneration, DataTypeLiteral, Declaration, Expression, Field, Iterator, IteratorQuery, LiteralSubject, NestedIterator, ObjectElement, PredicateObject, Prefix, QueryClause, ShExML, Shape, ShapeLink, ShapeVar, Source, URL, Var} +import com.herminiogarcia.shexml.ast.{Action, AutoIncrement, DataType, DataTypeGeneration, DataTypeLiteral, Declaration, Expression, Field, Iterator, IteratorQuery, LiteralSubject, NestedIterator, ObjectElement, ObjectOrShapeLink, PredicateObject, Prefix, QueryClause, ShExML, Shape, ShapeLink, ShapeVar, Source, URL, Var} class ShExMLPrinter { @@ -62,7 +62,8 @@ class ShExMLPrinter { } generateIndentation(indentation) + s.shapeName.name + " " + shapePrefix + "[" + shapeAction + "] {\n" + - s.predicateObjects.map(po => print(po, indentation + 1)).mkString("") + + s.predicateObjects.sortWith((l, r) => containsShapeLink((l.objectOrShapeLink, r.objectOrShapeLink))) + .map(po => print(po, indentation + 1)).mkString("") + "}\n" } @@ -108,4 +109,11 @@ class ShExMLPrinter { case DataTypeGeneration(prefix, action, matcher) => "" //to be supported }).getOrElse("") + val containsShapeLink: PartialFunction[(ObjectOrShapeLink, ObjectOrShapeLink), Boolean] = { + case (_: ShapeLink, _) => false + case (_, _: ShapeLink) => true + case _ => false + } + + } diff --git a/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala index 621b9c5..28748be 100644 --- a/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShExMLDeclarationsConverter.scala @@ -56,7 +56,7 @@ class XMLSchema2ShExMLDeclarationsConverter(schema: Schema, implicit val varTabl def convertAttributeElement(ae: AttributeElement): Field = { val name = normalizeName(ae.name, ae.ref) - Field(Var(name), FieldQuery(name), false, false) + Field(Var(name), FieldQuery("@" + name), false, false) } def convertSequence(e: ElementsHolder): List[AST] = { diff --git a/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala b/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala index 81b2dff..c4a98cc 100644 --- a/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala +++ b/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala @@ -33,7 +33,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | FIELD price <price> |} |ITERATOR shiporder <xpath: /shiporder> { - | FIELD orderid <orderid> + | FIELD orderid <@orderid> | FIELD orderperson <orderperson> | ITERATOR shipto <shipto> { | FIELD name <name> @@ -52,9 +52,9 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll("\\s", "")) output should include (""":shiporder :[exp.orderid] { | :orderperson [exp.orderperson] xs:string ; - | :shipto @:shipto ; - | :item @:item ; | :orderid [exp.orderid] xs:string ; + | :shipto @:shipto ; + | :item @:item ; |} |:item :[subjectAutoincrementId] { | :title [exp.item.title] xs:string ; @@ -80,7 +80,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { |SOURCE example <http://example.com/example.xml> |""".stripMargin.replaceAll("\\s", "")) output should include ("""ITERATOR shiporder <xpath: /shiporder> { - | FIELD orderid <orderid> + | FIELD orderid <@orderid> | FIELD orderperson <orderperson> | ITERATOR shipto <shipto> { | FIELD name <name> @@ -99,9 +99,9 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll("\\s", "")) output should include (""":shiporder :[exp.orderid] { | :orderperson [exp.orderperson] xs:string ; - | :shipto @:shipto ; - | :item @:item ; | :orderid [exp.orderid] xs:string ; + | :shipto @:shipto ; + | :item @:item ; |} |:item :[subjectAutoincrementId] { | :title [exp.item.title] xs:string ; @@ -158,10 +158,10 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { |SOURCE example <http://example.com/example.xml> |""".stripMargin.replaceAll("\\s", "")) output should include ("""ITERATOR purchaseOrder <xpath: /purchaseOrder> { - | FIELD orderDate <orderDate> + | FIELD orderDate <@orderDate> | FIELD comment <comment> | ITERATOR shipTo <shipTo> { - | FIELD country <country> + | FIELD country <@country> | FIELD name <name> | FIELD street <street> | FIELD city <city> @@ -169,7 +169,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | FIELD zip <zip> | } | ITERATOR billTo <billTo> { - | FIELD country <country> + | FIELD country <@country> | FIELD name <name> | FIELD street <street> | FIELD city <city> @@ -178,7 +178,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { | } | ITERATOR items <items> { | ITERATOR item <item> { - | FIELD partNum <partNum> + | FIELD partNum <@partNum> | FIELD productName <productName> | FIELD quantity <quantity> | FIELD USPrice <USPrice> @@ -190,11 +190,11 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { |EXPRESSION exp <example.purchaseOrder> |AUTOINCREMENT subjectAutoincrementId <"subject_" + 1 to 2147483647 by 1>""".stripMargin.replaceAll("\\s", "")) output should include ("""tn:purchaseOrder tn:[subjectAutoincrementId] { - | tn:shipTo @tn:shipTo ; - | tn:billTo @tn:billTo ; | tn:comment [exp.comment] xs:string ; - | tn:items @tn:items ; | tn:orderDate [exp.orderDate] xs:date ; + | tn:shipTo @tn:shipTo ; + | tn:billTo @tn:billTo ; + | tn:items @tn:items ; |} |tn:items tn:[subjectAutoincrementId] { | tn:item @tn:item ; From 4d3484e0ef5ed28dbb09657a303d885441d2e781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garc=C3=ADa=20Gonz=C3=A1lez?= <herminiogg@hotmail.com> Date: Fri, 19 Jan 2024 11:06:54 +0100 Subject: [PATCH 19/22] Fixed an error with the example domain prefix --- .../generation/XMLSchema2ShexCompletionGenerator.scala | 2 +- .../inputoutputtests/ShExMLGenerationTests.scala | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala index a1b6963..14cf613 100644 --- a/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/generation/XMLSchema2ShexCompletionGenerator.scala @@ -14,7 +14,7 @@ class XMLSchema2ShexCompletionGenerator(declarations: List[Declaration], shapes: def completePrefixes(): List[Declaration] = { List( - Declaration(Prefix(Var(":"), URL("http://example.org"))), + Declaration(Prefix(Var(":"), URL("http://example.com/"))), Declaration(Prefix(Var("xs:"), URL("http://www.w3.org/2001/XMLSchema#"))), Declaration(Prefix(Var("xsd:"), URL("http://www.w3.org/2001/XMLSchema#"))) ) diff --git a/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala b/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala index c4a98cc..9a14333 100644 --- a/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala +++ b/src/test/scala/com/herminiogarcia/xmlschema2shex/inputoutputtests/ShExMLGenerationTests.scala @@ -14,7 +14,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { test("Xml1 version") { val xml = Source.fromResource("xml1version.xsd").mkString val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll("\\s", "") - output should include ("""PREFIX : <http://example.org> + output should include ("""PREFIX : <http://example.com/> |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll("\\s", "")) output should include (""" @@ -73,7 +73,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { test("""Xml2 version""") { val xml = Source.fromResource("xml2version.xsd").mkString val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll("\\s", "") - output should include ("""PREFIX : <http://example.org> + output should include ("""PREFIX : <http://example.com/> |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll("\\s", "")) output should include (""" @@ -120,7 +120,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { test("XML Schema conversion for addresses") { val xml = Source.fromResource("address.xsd").mkString val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll("\\s", "") - output should include ("""PREFIX : <http://example.org> + output should include ("""PREFIX : <http://example.com/> |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>""".stripMargin.replaceAll("\\s", "")) output should include (""" @@ -150,7 +150,7 @@ class ShExMLGenerationTests extends AnyFunSuite with Matchers { test("""XML Schema conversion from Microsoft example""") { val xml = Source.fromResource("purchaseOrderFull.xsd").mkString val output = XMLSchema2ShexParser().convertToShExML(xml).stripMargin.replaceAll("\\s", "") - output should include ("""PREFIX : <http://example.org> + output should include ("""PREFIX : <http://example.com/> |PREFIX xs: <http://www.w3.org/2001/XMLSchema#> |PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> |PREFIX tn: <http://tempuri.org/po.xsd>""".stripMargin.replaceAll("\\s", "")) From 31c9d54146546220ac4d7eb4d9744b5634c00270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garc=C3=ADa=20Gonz=C3=A1lez?= <herminiogg@hotmail.com> Date: Mon, 22 Jan 2024 14:35:58 +0100 Subject: [PATCH 20/22] Added README.md --- README.md | 60 +++++++++++++++++++ .../herminiogarcia/xmlschema2shex/Main.scala | 2 +- .../parser/XMLSchema2ShexParser.scala | 2 +- 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f08961d --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# XMLSchema2ShEx +[![Master build](https://github.com/herminiogg/xmlschema2shex/actions/workflows/scala.yml/badge.svg?branch=master)](https://github.com/herminiogg/xmlschema2shex/actions/workflows/scala.yml?query=branch%3Amaster) +[![Maven Central](https://img.shields.io/maven-central/v/com.herminiogarcia/xmlschema2shex_3?color=blue)](https://central.sonatype.com/artifact/com.herminiogarcia/xmlschema2shex_3) + +XMLSchema2ShEx is a tool to convert XML Schema files to "equivalent" Shape Expressions files. The goal is to support +the translation from XML data to RDF, preserving the validation rules. It is based in the theoretical paper developed +in the companion paper (see the [Publications section](#publications)) and implements a subset of the defined +conversions (see the [Supported features section](#supported-features)). + +:heavy_exclamation_mark: A experimental conversion to ShExML is being tested in this library letting users to scaffold +the necessary mapping rules in a semi-automatic fashion and then validate the results. + +## Supported features +| Supported features | Pending implementation | +|:------------------:|:----------------------:| +| Complex type | Choice | +| Simple type | List | +| All | Union | +| Attributes | Extension | +| Restriction | Fraction Digits | +| Element | Length | +| Max exclusive | Max Length | +| Min exclusive | Min Length | +| Max inclusive | Total digits | +| Min inclusive | Whitespace | +| Enumeration | Unique | +| Pattern | | +| Cardinality | | + +## Usage +The library provides two methods of operation: a CLI through the provided JAR package and a JVM compatible API. + +### CLI +The CLI can be called using the command `$ java -jar XMLSchema2ShEx.jar [options]` where options are as described below: + +``` +Usage: XMLSchema2ShEx [-hsV] -i=<file> [-o=<output>] +Convert from XML Schema to ShEx and more... + -h, --help Show this help message and exit. + -i, --input=<file> Path to XML Schema file + -o, --output=<output> Path where the output file should be created + -s, --shexml Generate ShExML scaffold + -V, --version Print version information and exit. +``` + +### JVM compatible API +It can also be called from any JVM compatible language that has it as its dependency. The call +should look like similar to the following snippet: + +```scala +val shexResult = XMLSchema2ShexParser().parse(input) +val shexmlResult = XMLSchema2ShexParser().convertToShExML(input) +``` + +## Publications +For citation purposes please use the companion paper: +``` +Garcia-Gonzalez, H., & Labra-Gayo, J. E. (2020). XMLSchema2ShEx: +Converting XML validation to RDF validation. Semantic Web, 11(2), 235-253. +``` \ No newline at end of file diff --git a/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala index 8de388c..0e42d2e 100644 --- a/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala @@ -34,7 +34,7 @@ class Main extends Callable[Int] { val result = if (shexml) { XMLSchema2ShexParser().convertToShExML(input) } else { - XMLSchema2ShexParser().parse(input, None) + XMLSchema2ShexParser().parse(input) } if (output.nonEmpty) { val fw = new FileWriter(output) diff --git a/src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchema2ShexParser.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchema2ShexParser.scala index 907f132..edcfd4d 100644 --- a/src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchema2ShexParser.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/parser/XMLSchema2ShexParser.scala @@ -13,7 +13,7 @@ import scala.collection.mutable */ case class XMLSchema2ShexParser() extends XMLSchemaParser { - def parse(xmlSchema: String, context: Option[String]): String = { + def parse(xmlSchema: String, context: Option[String] = None): String = { val xmlSchemaWithoutComments = removeComments(xmlSchema) val schema = parseAll(root, xmlSchemaWithoutComments).get new SemanticChecker(schema).check() From 511cd492677cc03a38e01eec180bd8235c737014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garc=C3=ADa=20Gonz=C3=A1lez?= <herminiogg@hotmail.com> Date: Mon, 22 Jan 2024 14:43:09 +0100 Subject: [PATCH 21/22] Version 0.1.0 --- LICENSE | 21 +++++++++++++++++++ README.md | 2 +- .../herminiogarcia/xmlschema2shex/Main.scala | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..84fbfd2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 XMLSchema2ShEx + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index f08961d..b1066f1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ the translation from XML data to RDF, preserving the validation rules. It is bas in the companion paper (see the [Publications section](#publications)) and implements a subset of the defined conversions (see the [Supported features section](#supported-features)). -:heavy_exclamation_mark: A experimental conversion to ShExML is being tested in this library letting users to scaffold +:heavy_exclamation_mark: An experimental conversion to ShExML is being tested in this library letting users to scaffold the necessary mapping rules in a semi-automatic fashion and then validate the results. ## Supported features diff --git a/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala b/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala index 0e42d2e..fd50be8 100644 --- a/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala +++ b/src/main/scala/com/herminiogarcia/xmlschema2shex/Main.scala @@ -13,7 +13,7 @@ object Main { } } -@Command(name = "XMLSchema2ShEx", version = Array("v0.1.1"), +@Command(name = "XMLSchema2ShEx", version = Array("v0.1.0"), mixinStandardHelpOptions = true, description = Array("Convert from XML Schema to ShEx and more...")) class Main extends Callable[Int] { From b0268e25e0eb5ce26e063ad03dbde5935ade5e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herminio=20Garc=C3=ADa=20Gonz=C3=A1lez?= <herminiogg@hotmail.com> Date: Mon, 22 Jan 2024 14:50:33 +0100 Subject: [PATCH 22/22] Configuration files for deploying the first release --- build.sbt | 8 +++++++- project/plugins.sbt | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 26675b1..85df064 100644 --- a/build.sbt +++ b/build.sbt @@ -12,5 +12,11 @@ lazy val xmlschema2shex = project "org.scalatest" %% "scalatest" % "3.2.15" % "test", "com.herminiogarcia" %% "shexml" % "0.4.2" exclude("io.gatling", "gatling-jsonpath"), "info.picocli" % "picocli" % "4.7.3", - ) + ), + assembly / assemblyMergeStrategy := { + case PathList("META-INF", "services", xs@_*) => MergeStrategy.concat + case PathList("META-INF", xs@_*) => MergeStrategy.discard + case x => MergeStrategy.first + } + ) \ No newline at end of file diff --git a/project/plugins.sbt b/project/plugins.sbt index 14a6ca1..ed870f6 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1 +1,3 @@ -logLevel := Level.Warn \ No newline at end of file +logLevel := Level.Warn +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.10") +addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") \ No newline at end of file