我有一个很长的切换声明,我正在努力提高效率。 它解析xml提要并使用xml值填充Java对象。 可能有30个字段,因此编写一个开关盒有点乏味 对于每个领域。
switch (currentTagName) {
case "longitude" :
observation.setLongitude(Double.parseDouble(parser.getText()));
break;
case "elevation" :
observation.setElevation(Integer.parseInt(parser.getText()));
break;
case "observation_time" :
observation.setObservation_time(parser.getText());
break;
您可以看到,处理每个案例的唯一区别是由于我正在使用的数据类型。
我正在试图弄清楚做类似的事情(伪代码)的语法:
//get the data type of this variable, somehow or other
String inputType = Observation.getMethodInputType("set" + currentTagName);
//switch on that data type
switch(inputType) {
case "Integer":
observation.set{currentTagName}(Integer.parseInt(parser.getText()));
break;
case "Double":
observation.set{currentTagName}(Double.parseDouble(parser.getText()));
break;
case "String":
observation.set{currentTagName}(parser.getText());
break;
}
只是我的Java语法非常生疏,我不确定这样做的正确方法是什么(或者如果你能做到的话), 特别是对于set {currentTagName} part和getMethodInputType()(那是一个什么东西?)。
这样做的正确方法是什么?
答案 0 :(得分:3)
您的解决方案将非常难以维护。 Java几乎没有以紧凑的方式解析xml的流行方法(没有繁琐的字符串操作)。
你应该检查:
对于JAXB,您必须创建将重新创建xml结构的对象/对象,并且将自动进行转换。
答案 1 :(得分:1)
不要使用switch
。创建一个界面,用于按类型将String
转换为对象,使用适当类型的转换器填充Map<Class,Converter>
,并使用该地图中的转换器来解析您的输入。
interface Converter {
Object convert(String s);
}
private static Map<Class,Converter> converterForClass = new HashMap<>();
static {
converterForClass.put(Integer.TYPE, s -> Integer.parseInt(s));
converterForClass.put(Double.TYPE, s -> Double.parseDouble(s));
converterForClass.put(String.class, s -> s);
converterForClass.put(Long.TYPE, s -> Long.parseLong(s));
};
现在,您可以将String
转换为适当类型的Object
,如下所示:
Object a = converterForClass.get(Integer.TYPE).convert("123");
这是一个使用反射访问该字段的演示:
static class Demo {
public int a;
public long b;
public String c;
public double d;
@Override
public String toString() {
return a+":"+b+":'"+c+"':"+d;
}
}
public static void main (String[] args) throws java.lang.Exception
{
Object a = new Demo();
Map<String,String> data = new HashMap<>();
data.put("a", "123");
data.put("b", "123456678789898");
data.put("c", "HELLO");
data.put("d", "123.456");
for (Field f : Demo.class.getDeclaredFields()) {
f.setAccessible(true);
String str = data.get(f.getName());
Object r = converterForClass.get(f.getType()).convert(str);
f.set(a, r); // Call set(target, objValue) instead of setInt, setLong, etc.
}
System.out.println(a);
}
答案 2 :(得分:1)
您可以使用以下命令将其转换为对象并获取其类名:
((Object) yourVar).getClass().getName()
然后你可以在你的switch语句中使用它:
String typeName = ((Object) inputType).getClass().getName();
switch(typeName) {
case "Integer":
observation.set{currentTagName}(Integer.parseInt(parser.getText()));
break;
case "Double":
observation.set{currentTagName}(Double.parseDouble(parser.getText()));
break;
case "String":
observation.set{currentTagName}(parser.getText());
break;
}
请查看How to determine the primitive type of a primitive variable?以获取更多信息。
答案 3 :(得分:0)
将int和double转换为字符串,然后使用一个if语句。使用以下语法:
Integer.toString(i)
//Makes an integer into a string
和
Double.toString(i)
//Makes a double into a string
将所有内容都作为字符串后,比较字符串。这种方式变量类型是相同的,它使代码更容易处理。
祝你好运!答案 4 :(得分:0)
我已经编写了一个名为unXml的小型Java-8库,可能对您有所帮助。它在Github上开源,可在Maven Central上获得。
您可以创建ObjectParser
,从XPath
中挑选一个值,并将其作为属性放入JsonObject
。然后它使用Jackson的json-mapping来实例化你的课程。
阅读Jacksons Json to Object mapping,了解如何最好地融入您的班级。
示例:的
<root>
<entry id="1">
<observation>100</observation>
<longitude>150</longitude>
<observation-time>15 sec</observation-time>
</entry>
</root>
让我们说你的专业领域是鸟类,这是你的班级:
@JsonIgnoreProperties(ignoreUnknown = true)
public static class BirdSpotting {
public Integer id;
public Integer observation;
public Double longitude;
public String observationTime;
}
您可以为xml创建一个(可重复使用的)ObjectParser
和apply
。
public List<BirdSpotting> getData(Document inputXml) {
Parsing parsing = ParsingFactory.getInstance().create();
ObjectParser<List<BirdSpotting>> parser =
parsing.arr("/root/entry", parsing.obj()
.attribute("id", "@id")
.attribute("observation", "observation", parsing.with(Integer::parseInt))
.attribute("longitude", "longitude", parsing.with(Double::parseDouble))
.attribute("observationTime", "observation-time")
).as(BirdSpotting.class);
List<BirdSpotting> spottings = parser.apply(inputXml);
return spottings;
}
您还可以通过删除Birdspotting
部分来解析为单个parsing.arr()
对象。您的parser
将为ObjectParser<Birdspotting>
类型(不含List
)。
输出
BirdSpotting [id=1,observation=100,longitude=150.0,observationTime="15 sec"]