SimpleXML 框架:元素与元素或文本
SimpleXML framework: element with element or text
我必须解析 XML 可以有两种形式:
<Command><Variable/></Command>
或:
<Command>some text</Command>
我该怎么做?当我尝试在 class 中声明 @Element
和 @Text
负责 Command
解析时,当我尝试将 XML 解析为此 class.
我当前的代码版本:
@Root(name = "Command", strict = false)
public class AppCommand {
@Element(name = "Variable", required = false)
@Getter
private Variable variable;
@Text(required = false)
@Getter
private String content;
}
例外情况是:Text annotation @org.simpleframework.xml.Text(required=false, empty=, data=false) on field 'content' private java.lang.String com.example.AppCommand.content used with elements in class com.example.AppCommand
是的,Simple 无法处理这个问题。
Command.java
:
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Text;
@Root
public class Command {
@Element(required = false, name = "Variable")
private Variable variable;
@Text(required = false)
private String text;
}
Variable.java
:
class Variable {
}
SOPlayground.java
:
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
public class SOPlayground {
public static void main(String[] args) throws Exception {
Serializer serializer = new Persister();
String xml1 = "<Command><Variable/></Command>";
String xml2 = "<Command>some text</Command>";
serializer.validate(Command.class, xml1);
serializer.validate(Command.class, xml2);
}
}
这会编译但不会 运行:
Exception in thread "main" org.simpleframework.xml.core.TextException: Text annotation @org.simpleframework.xml.Text(data=false, required=false, empty=) on field 'text' private java.lang.String de.lhorn.so.Command.text used with elements in class de.lhorn.so.Command
看起来不能同时拥有 @Element
和 @Text
成员。
我的解决方案(不漂亮,但有效并且不需要太多工作即可实现):
private static class SerializerWithPreprocessor extends Persister {
public SerializerWithPreprocessor(RegistryMatcher matcher, Format format) {
super(matcher, format);
}
@Override
public <T> T read(Class<? extends T> type, String source) throws Exception {
source = source.replaceFirst("<Command (.*)>([[\w||[+=]]&&[^<>]]+)</Command>", "<Command ><Content></Content></Command>");
return super.read(type, source);
}
}
所以我刚刚创建了新的 Serializer class。这个class使用正则表达式将Command
里面的Text
元素变成正常的Element
。然后我可以使用:
@Root(name = "Command", strict = false)
public class AppCommand {
@Element(name = "Variable", required = false)
@Getter
private Variable variable;
@Element(name = "Content", required = false)
@Getter
private String content;
}
在反序列化过程中,一切都如我所愿。
我必须解析 XML 可以有两种形式:
<Command><Variable/></Command>
或:
<Command>some text</Command>
我该怎么做?当我尝试在 class 中声明 @Element
和 @Text
负责 Command
解析时,当我尝试将 XML 解析为此 class.
我当前的代码版本:
@Root(name = "Command", strict = false)
public class AppCommand {
@Element(name = "Variable", required = false)
@Getter
private Variable variable;
@Text(required = false)
@Getter
private String content;
}
例外情况是:Text annotation @org.simpleframework.xml.Text(required=false, empty=, data=false) on field 'content' private java.lang.String com.example.AppCommand.content used with elements in class com.example.AppCommand
是的,Simple 无法处理这个问题。
Command.java
:
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Text;
@Root
public class Command {
@Element(required = false, name = "Variable")
private Variable variable;
@Text(required = false)
private String text;
}
Variable.java
:
class Variable {
}
SOPlayground.java
:
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
public class SOPlayground {
public static void main(String[] args) throws Exception {
Serializer serializer = new Persister();
String xml1 = "<Command><Variable/></Command>";
String xml2 = "<Command>some text</Command>";
serializer.validate(Command.class, xml1);
serializer.validate(Command.class, xml2);
}
}
这会编译但不会 运行:
Exception in thread "main" org.simpleframework.xml.core.TextException: Text annotation @org.simpleframework.xml.Text(data=false, required=false, empty=) on field 'text' private java.lang.String de.lhorn.so.Command.text used with elements in class de.lhorn.so.Command
看起来不能同时拥有 @Element
和 @Text
成员。
我的解决方案(不漂亮,但有效并且不需要太多工作即可实现):
private static class SerializerWithPreprocessor extends Persister {
public SerializerWithPreprocessor(RegistryMatcher matcher, Format format) {
super(matcher, format);
}
@Override
public <T> T read(Class<? extends T> type, String source) throws Exception {
source = source.replaceFirst("<Command (.*)>([[\w||[+=]]&&[^<>]]+)</Command>", "<Command ><Content></Content></Command>");
return super.read(type, source);
}
}
所以我刚刚创建了新的 Serializer class。这个class使用正则表达式将Command
里面的Text
元素变成正常的Element
。然后我可以使用:
@Root(name = "Command", strict = false)
public class AppCommand {
@Element(name = "Variable", required = false)
@Getter
private Variable variable;
@Element(name = "Content", required = false)
@Getter
private String content;
}
在反序列化过程中,一切都如我所愿。