XML schema data types like xs:Name [message #1062215] |
Thu, 06 June 2013 10:24  |
Eclipse User |
|
|
|
Hey,
was wondering if sapphire supports certain schema types like xs:ID, xs:Name and xs:NCName. One element in my schema uses the xs:Name type. Currently, I can fill the text field for the element in the Design View with any string, also with 1myName and no error is shown. If I switch to the source view, the xml editor creates an error marker and that 1Name does not conform the xs:Name type (must not start with with a number).
Thank you.
Kon
|
|
|
Re: XML schema data types like xs:Name [message #1062279 is a reply to message #1062215] |
Thu, 06 June 2013 19:34   |
Eclipse User |
|
|
|
Sapphire does not validation per XML Schema, but you can certainly specify validation rules to cover what the schema requires and much more. A number of annotations such as @Required, @PossibleValues, @NumericRange, etc. result in validation. For maximum flexibility, you can implement a custom ValidationService and attach it to a property using @Service annotation. Examples in the samples project.
In Sapphire 0.7, there is also an @Validation annotation that allows custom validation rules to be specified using EL. For instance:
@Validation
(
rule = "${ Scale( Discount, 2 ) <= Scale( Subtotal, 2 ) + Scale( Delivery, 2 ) }",
message = "Discount must not exceed subtotal plus delivery charge."
)
There isn't a regex function in EL, but we can add one if that would be useful.
|
|
|
|
|
|
|
Re: XML schema data types like xs:Name [message #1066636 is a reply to message #1065800] |
Wed, 03 July 2013 10:07   |
Eclipse User |
|
|
|
Hey Konstantin,
I'm trying to implement some custom custom validation service but having difficulties to access all Value<T>s, storing the the id. I'm just able to get a collection of strings.
My model has following structure:
- ElementA [1-1]
\- Id
\- ElementB [0-*]
\- Id
\- ElementC [0-*]
\- Id
Every Id is tagged with following annotations:
@Required
@DependsOn({ "/Id", "/ElementB/Id", "/ElementB/ElementC/Id" })
@Service(impl = IDValidationService.class)
ValueProperty PROP_ID = new ValueProperty(TYPE, "Id");
Value<String> getId();
void setId(String value);
I use absolute paths being able to compare the changed id against every other id that occurs in my file.
My validation method of my custom validation service:
@Override
public Status isValid(String name) {
if (!isValidContent(name)) {
return Status.createErrorStatus(getErrorMessage(name));
}
// here the actual interesting part
Value<?> value = context(IModelElement.class).read(context(ValueProperty.class));
List<DependenciesService> services = context(IModelElement.class).services(context(ModelProperty.class), DependenciesService.class);
for (DependenciesService dependenciesService : services) {
Set<ModelPath> dependencies = dependenciesService.dependencies();
for (ModelPath path : dependencies) {
SortedSet<String> read = ((IModelElement) context(IModelElement.class).root()).read(path);
System.out.println(String.format("%s %s", path, read));
// ... perform validation value against the collections content
}
}
return Status.createOkStatus();
}
Unfortunately, the method call read(ModelPath) returns a list of strings. I would need the actual values being able to exclude value from the comparison. In addition, ids with the same string content are aggregated to one due to the SortedSet implementation.
Thank you.
Kon
|
|
|
|
|
Re: XML schema data types like xs:Name [message #1074216 is a reply to message #1067864] |
Fri, 26 July 2013 05:47  |
Eclipse User |
|
|
|
Hey,
I updated to 0.7 and could make the xs:ID type validation work. xs:ID extends xs:NCName and it's value is unique for the whole document. I implemented the following validation service:
import java.util.List;
import org.eclipse.sapphire.Element;
import org.eclipse.sapphire.Property;
import org.eclipse.sapphire.Value;
import org.eclipse.sapphire.ValueProperty;
import org.eclipse.sapphire.modeling.ModelPath;
import org.eclipse.sapphire.services.DependenciesService;
public class IDValidationService extends NCNameValidationService {
@Override
public boolean isValidContent(String name) {
if (!org.apache.xerces.util.XMLChar.isValidNCName(name)) {
return false;
}
Value<?> value = context(Element.class).property(context(ValueProperty.class));
List<DependenciesService> services = value.services(DependenciesService.class);
for (DependenciesService dependenciesService : services) {
for (ModelPath path : dependenciesService.dependencies()) {
for (Property property : value.root().properties(path)) {
if (!(property instanceof Value<?>)) {
continue;
}
Value<?> otherValue = (Value<?>) property;
if (otherValue.equals(value)) {
continue;
}
if (otherValue.text().equals(value.text())) {
return false;
}
}
}
}
return true;
}
}
And here the annotation for the id property:
@DependsOn({ "/Id", "/a/Id", "/a/b/Id" })
@Service(impl = IDValidationService.class)
ValueProperty PROP_ID = new ValueProperty(TYPE, "Id");
You need to specify all xs:ID appearances in your model with a absolute path. If the property is modified, it will be compared against every other xs:ID in the model.
Kon
|
|
|
Powered by
FUDForum. Page generated in 0.28747 seconds