在我的XML文件中,我有这样的行;
<text id="name">Bu ilk rule</text>
<text id="bundleName">Rule.behavior</text>
所以我的Text类是这样的:
@XStreamConverter(value = ToAttributedValueConverter.class, strings = {"value"})
@XStreamAlias("text")
public class Text {
@XStreamAsAttribute
String id = "unset";
String value = "0";
}
它有效。但今天我用XML得到了这个:
<text id="targetAttribute">game.devices.touches.touch1.y</text>
<text id="RHS">
<expression>
<string>acos(x)</string>
</expression>
</text>
它不起作用。如果我删除@XStreamConverter
,我会得到这样的输出:
<text id="targetAttribute"/>
<text id="RHS">
<expression>
<string>acos(x)</string>
</expression>
</text>
这是什么解决方法?
修改
马蒂亚斯回答后,我能得到最接近的格式是:
<text id="RHS">
<expression>
<string>acos(x)</string>
</expression>
</text>
但是这种方法失败了,它开始没有显示“值”字段:
<text id="name"/>
<text id="bundleName"/>
<text id="targetAttribute"/>
使用这个课程:
@XStreamAlias("text")
class Test {
@XStreamAsAttribute
String id = "unset";
String value = "0";
myString string = new myString();
Expression expression = new Expression();
}
另外,我这样做的阅读,所以在这样做时必须有效:
String xml1 = readFile("C:\\1.xml");
Actor actorNew = (Actor) xstream.fromXML(xml1);
String xmlNew = xstream.toXML(actorNew);
System.out.println(xmlNew);
EDIT2:
XML中<string>
的myString类:
@XStreamConverter(value = ToAttributedValueConverter.class, strings = {"value"})
public class myString {
@XStreamAlias("string")
String value = "";
}
这是我正在尝试阅读的XML的缩小视图:
<behaviors>
<behavior id="id384781" class="ChangeAttributeAction" enabled="true">
<attributes>
<text id="name">Change Attribute</text>
<text id="bundleName">ChangeAttribute.behavior</text>
<text id="targetAttribute">game.devices.touches.touch1.y</text>
<text id="RHS">
<expression>
<string>acos(x)</string>
</expression>
</text>
</attributes>
</behavior>
</behaviors>
所有工作都在工作,直到id =“RHS”的文本
EDIT3:
我在自定义转换器上尝试了类似的功能,但没有工作:
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Test test = new Test();
test.expression = new Expression();
test.expression.string = new myString();
test.value = reader.getValue();
test.id = reader.getAttribute("id");
reader.moveDown();
reader.moveDown();
test.expression.string.value = reader.getValue();
return test;
}
Edit4
WOOOOOOOOOOOOOOOOOOOOOO我最后得到了它!
我是这样做的:
class ValueConverter implements Converter {
@Override
public boolean canConvert(Class type) {
return Test.class.isAssignableFrom(type);
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
Test src = (Test) source;
writer.addAttribute("id", src.id);
writer.setValue(src.value);
if (src.expression.string.value.length() > 0) {
writer.startNode("expression");
writer.startNode("string");
writer.setValue(src.expression.string.value);
writer.endNode();
}
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Test test = new Test();
test.id = reader.getAttribute("id");
test.value = reader.getValue();
if (reader.hasMoreChildren()) {
reader.moveDown();
reader.moveDown();
test.expression.string.value = reader.getValue();
}
return test;
}
}
答案 0 :(得分:1)
嗯,您显示的代码无法生成此XML。我猜你真正的代码中有一些继承(一个扩展你的Test类的类Expression),它产生了这个结果。似乎ToAttributedValueConverter
对派生类不起作用,并在那里被忽略。
如果您想要映射到非常特定的XML表示的更复杂的对象结构,则应使用转换器。有疑问,您始终可以创建一个处理编组/解组的自定义转换器。
对于这些转换器,您可以轻松定义应使用哪些类(请参阅canConvert(Class)
方法。
我为你做了一个非常相似的代码:
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
@XStreamAlias("text")
class Test {
String id = "unset";
String value = "0";
}
@XStreamAlias("expression")
class Expression extends Test {
Expression() {
value = "acos(x)";
}
}
class ValueConverter implements Converter {
@Override
public boolean canConvert(Class type) {
return Test.class.isAssignableFrom(type);
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
Test src = (Test)source;
writer.addAttribute("id", src.id);
writer.setValue(src.value);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Test test = new Test();
test.value = reader.getValue();
test.id = reader.getAttribute("id");
return test;
}
}
public class Example {
public static void main(String[] args) {
XStream xStream = new XStream();
xStream.autodetectAnnotations(true);
System.out.println("BEFORE setting a converter:");
System.out.println(xStream.toXML(new Test()));
System.out.println(xStream.toXML(new Expression()));
xStream.registerConverter(new ValueConverter());
System.out.println("\nAFTER setting a converter:");
System.out.println(xStream.toXML(new Test()));
System.out.println(xStream.toXML(new Expression()));
}
}
运行此命令,您将获得以下输出:
<text>
<id>unset</id>
<value>0</value>
</text>
<expression>
<id>unset</id>
<value>acos(x)</value>
</expression>
AFTER setting a converter:
<text id="unset">0</text>
<expression id="unset">acos(x)</expression>
答案 1 :(得分:1)
我是通过更改提到的转换器MAtthias来完成的;
class ValueConverter implements Converter {
@Override
public boolean canConvert(Class type) {
return Test.class.isAssignableFrom(type);
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
Test src = (Test) source;
writer.addAttribute("id", src.id);
writer.setValue(src.value);
if (src.expression.string.value.length() > 0) {
writer.startNode("expression");
writer.startNode("string");
writer.setValue(src.expression.string.value);
writer.endNode();
}
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Test test = new Test();
test.id = reader.getAttribute("id");
test.value = reader.getValue();
if (reader.hasMoreChildren()) {
reader.moveDown();
reader.moveDown();
test.expression.string.value = reader.getValue();
}
return test;
}
}