Java XStream和使用';至分配值转换器';用于两个相似但不同的XML字段

Java XStream和使用';至分配值转换器';用于两个相似但不同的XML字段,java,xstream,Java,Xstream,在我的XML文件中,我有这样的行 <text id="name">Bu ilk rule</text> <text id="bundleName">Rule.behavior</text> 它是有效的。但今天我在XML中得到了这个: <text id="targetAttribute">game.devices.touches.touch1.y</text> <text

在我的XML文件中,我有这样的行

    <text id="name">Bu ilk rule</text>
    <text id="bundleName">Rule.behavior</text>
它是有效的。但今天我在XML中得到了这个:

        <text id="targetAttribute">game.devices.touches.touch1.y</text>
        <text id="RHS">
          <expression>
            <string>acos(x)</string>
          </expression>
        </text>
解决这个问题的方法是什么

编辑:

在Matthias的回答之后,我能得到的最接近所需格式的是:

        <text id="RHS">
          <expression>
            <string>acos(x)</string>
          </expression>
        </text>
另外,我的阅读方式是这样的,所以在这样做时,它必须起作用:

String xml1 = readFile("C:\\1.xml");
Actor actorNew = (Actor) xstream.fromXML(xml1);

String xmlNew = xstream.toXML(actorNew);
System.out.println(xmlNew);
Edit2:

XML中
的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>
Edit4

呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜

我是这样做的:

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;
    }

}

那么,您显示的代码无法生成这种XML。我猜在实际代码的某个地方,有一些继承(扩展测试类的类表达式)产生了这个结果。似乎
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>

取消
0
取消
助理文书主任(x)
设置转换器后:
0
助理文书主任(x)

我是通过改变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;
    }

}

嘿,谢谢你的回答,我已经玩了一段时间了,但还是没能用。我更新了这个问题。在你的回答中,格式不同,
应该在
结束之前开始。我想我应该修补一下ValueConverter,但我无法使用。你也可以发布Expr的代码吗Session类?我会看看是否可以使用它。我在Expression类上没有任何东西,只是添加了
myString string=new myString();
,看看它是否会有什么不同。现在我将用myString类更新这个问题。我不能再进一步了,你有什么消息吗?:)XStream不会看到
类及其子类
。我编写了不同的转换器,但即使我得到了所需的格式,我也无法得到值,在我们的例子中是acos(x)。我不需要手动输入,它应该从XML中读取,但它不能。
@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;
}
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;
    }

}
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>
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;
    }

}