如何在Xtext语法中为缺失的可选x/y属性设置默认值0
问题描述
我使用如下Xtext语法读取CXML文件:
CXML输入示例
<WINDOW id="0" name="BUTTON" width="2560" height="1024" x="0" y="0"/> <WINDOW id="1" name="CONSOLE" width="768" height="1024" />
现有语法规则
terminal INTEGER returns ecore::ELong: '"' ( ( ('-')?('0'..'9')+ ) | ( (('0x')|('0X'))(('0'..'9')|('A'..'F')|('a'..'f'))+ ) ) '"'; WindowConfigXtext: '<WINDOW' 'id='windowID=INTEGER 'name='windowName=ID 'width='width=INTEGER 'height='height=INTEGER ('x='x=INTEGER)? ('y='y=INTEGER)?'/>';
当前x、y为可选属性,我需要实现当CXML中不存在x、y时,将其值设为0而非NULL,请问该如何配置?
解决方案
要实现可选属性x、y默认值为0,有两种可靠的常用方式:
方法一:在Ecore模型中设置默认值
- 打开项目对应的
.ecore模型文件 - 找到
WindowConfigXtext类的x和y属性 - 分别给这两个属性设置默认值为
0 - 右键项目 → 选择
Run As→Generate Xtext Artifacts,重新生成代码
解析CXML时,若x或y属性不存在,模型实例会自动将这两个属性初始化为0。
方法二:自定义Xtext初始化器
如果不想修改Ecore模型,可通过初始化器强制设置默认值:
- 创建一个继承自
AbstractInstanceInitializer<WindowConfigXtext>的类,重写初始化方法:
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; import your.package.name.WindowConfigXtext; public class WindowConfigInitializer extends AbstractInstanceInitializer<WindowConfigXtext> { @Override public void initialize(WindowConfigXtext instance, Procedure1<? super WindowConfigXtext> initializer) { super.initialize(instance, initializer); if (instance.getX() == null) { instance.setX(0L); } if (instance.getY() == null) { instance.setY(0L); } } }
- 在项目的RuntimeModule类(如
YourDslRuntimeModule)中绑定这个初始化器:
import org.eclipse.xtext.common.types.xtext.AbstractInstanceInitializer; public class YourDslRuntimeModule extends AbstractYourDslRuntimeModule { @Override public Class<? extends AbstractInstanceInitializer<?>> bindAbstractInstanceInitializer() { return WindowConfigInitializer.class; } }
- 重新生成Xtext代码并运行项目
注意事项
由于你的INTEGER终端规则返回ecore::ELong(对应Java的Long类型),设置默认值时要使用0L而非0,避免类型不匹配问题。
内容的提问来源于stack exchange,提问作者user2320492
相关产品推荐
相关产品推荐

