2014-10-28 22 views
0

我摆弄着一个想法,但无法控制它。从xml在Java中的动态属性

我有一个包含100多个属性的xml文件,它定义了一个有点大的程序的运行时环境。这些通过一个类被暴露为变量。目前,对于xml文件中的每个选项,类中都有一个变量加上public getter和private setter。

每次我们需要一个新选项时,我们必须在xml文件中定义它,并在RuntimenEnvironment类中创建变量plus方法。

现在,我想要做的是这样的:我想以这种方式重写类,它从xml文件公开新选项作为变量,而不必触摸类。

我的XML文件,使用这样的结构:

<option> 
    <name>theName</name> 
    <type>eg int</type> 
    <value>20</value> 
    <constant>THE_NAME</constant> 
</option> 

我可以编写代码在Java中,在运行时动态创建的VAR和暴露他们通过一个方法,无需实际编写方法?

这可能吗?

由于提前,

克里斯

回答

1

的我能想到的选项情侣细节:

  • 如果名字是唯一一个地图可以用名称作为键来填充。

  • 如果您只对选项感兴趣,则选项列表可以是从XML填充的 。

下面是用SAX解析器实现

处理类

public class OptionsParser extends DefaultHandler { 
    private final StringBuilder valueBuffer = new StringBuilder(); 
    private final Map<String, Option> resultAsMap = new HashMap<String, Option>(); 
    private final List<Option> options = new ArrayList<Option>(); 

    //variable to store the values from xml temporarily 
    private Option temp; 

    public List<Option> getOptions() { 
     return options; 
    } 

    public Map<String, Option> getResultAsMap() { 
     return resultAsMap; 
    } 

    @Override 
    public void startElement(final String uri, final String localName, final String qName, 
      final Attributes attributes) throws SAXException { 
     if("option".equalsIgnoreCase(qName)) { 
      temp = new Option(); 
     } 
    } 

    @Override 
    public void endElement(final String uri, final String localName, final String qName) 
      throws SAXException { 
     //read the value into a string to set them to option object 
     final String value = valueBuffer.toString().trim(); 
     switch (qName) { 
     case "name": 
      temp.setName(value); 
      // set the value into map and name of the option is the key 
      resultAsMap.put(value, temp); 
      break; 
     case "type": 
      temp.setType(value); 
      break; 
     case "value": 
      temp.setValue(value); 
      break; 
     case "constant": 
      temp.setConstant(value); 
      break; 
     case "option": 
      // this is the end of option tag add it to the list 
      options.add(temp); 
      temp = null; 
      break; 
     default: 
      break; 
     } 
     //reset the buffer after every iteration 
     valueBuffer.setLength(0); 
    } 

    @Override 
    public void characters(final char[] ch, final int start, final int length) 
      throws SAXException { 
     //read the value into a buffer 
     valueBuffer.append(ch, start, length); 
    } 
} 

选项POJO

public class Option { 

    private String name; 
    private String type; 
    private String value; 
    private String constant; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getType() { 
     return type; 
    } 

    public void setType(String type) { 
     this.type = type; 
    } 

    public String getValue() { 
     return value; 
    } 

    public void setValue(String value) { 
     this.value = value; 
    } 

    public String getConstant() { 
     return constant; 
    } 

    public void setConstant(String constant) { 
     this.constant = constant; 
    } 
} 

输入X中的样本代码ML

<options> 
    <option> 
     <name>option1</name> 
     <type>int</type> 
     <value>20</value> 
     <constant>const1</constant> 
    </option> 
    <option> 
     <name>option2</name> 
     <type>string</type> 
     <value>testValue</value> 
     <constant>const2</constant> 
    </option> 
</options> 

样品主要类

public class ParseXML { 
     public static void main(String[] args) { 
      final OptionsParser handler = new OptionsParser(); 
      try { 
       SAXParserFactory.newInstance().newSAXParser() 
         .parse("C:/luna/sample/inputs/options.xml", handler); 
      } catch (SAXException | IOException | ParserConfigurationException e) { 
       System.err.println("Somethig went wrong while parsing the input file the exception is -- " + e.getMessage() + " -- "); 
      } 
      Map<String, Option> result = handler.getResultAsMap(); 
      Collection<Option> values = result.values(); 
      for (Option option : values) { 
       System.out.println(option.getName()); 
      } 

     } 
    } 
+0

作品完美无瑕 - 感谢您的回答 – siliconchris 2014-10-30 18:55:25

+0

@siliconchris:很高兴它帮助你! – Hari 2014-10-31 06:13:31

0

我将谈论JSON配置文件。但是XML也应该是相似的。杰克逊提供了反序列化JSON并创建动态对象的方式。 如果您的选项名称(theName)是唯一的,您可以创建动态bean。那么您的XML看起来像:

<theName> 
    <type>eg int</type> 
    <value>20</value> 
    <constant>THE_NAME</constant> 
</theName> 

见,我说的是JSON,所以它实际上是:

theName: { 
     type: "int" 
     value: 20 
     constant: "THE_NAME" } 

动态豆类食品含有一种地图,让您的选择将被存储在一个Map<String, Option>,其中Option是包含type,valueconstant字段的POJO。 您应该可以通过迭代地图来访问您的选项。不需要动态创建变量。 这blog entry已得到有关如何将JSON转换成POJO