【问题标题】:How can i make java class at runtime by parsing xml which contains only name of data members and their data types?如何通过解析仅包含数据成员名称及其数据类型的 xml 在运行时创建 java 类?
【发布时间】:2017-12-24 21:47:23
【问题描述】:

XML:

<data_format>
    <data_length>15</data_length> <!-- -1 for unknown -->
    <start_charater>$</start_charater>
    <end_character1>B</end_character1>
    <end_character2>E</end_character2>
    <no_of_parameter>2</no_of_parameter>
    <parameter>
        <start_charater>A</start_charater>
        <data_name>Azimuth</data_name>
        <data_type>char</data_type>
        <size>5</size>
    </parameter>
    <parameter>
        <start_charater>R</start_charater>
        <data_name>Range</data_name>
        <data_type>char</data_type>
        <size>5</size>
    </parameter>
</data_format>

我应该如何将这种以 XML 编码的信息转换为可以包含这种结构的类?我需要在运行时完成此操作。我从通过某个端口接收的数据包中获取方位角和范围的数据,并且需要一个结构来保存我不想硬编码但想在运行时在解析该 XML 时生成它的数据。这样做的目的是增加我的应用程序的通用性。

例子:

<!-- for this xml -->
  <data>
    <data_member name="name" type="String"></data_member>
    <data_member name="id" type="int"></data_member>
  </data>

而我想要的 Java 类是:

class Data
  {
     private String name;
     private int id;
     public String getName()
      {
        return name;
      }
      public void setName(name)
      {
        this.name=name;
      }
      public int getId()
      {
        return id;
      }
      public void setId(id)
      {
        this.id=id;
      }
}

【问题讨论】:

  • 你能添加一个你想要动态创建的类定义吗?但恐怕你不能说“我想要用字段 a、b 和 c 扩展 Object 的新类 DataHolder”这样的话。请更好地说明您想要实现的目标...
  • 找到this,但不确定它有什么帮助。您的其余代码如何知道如何调用这个动态生成的类的方法?请添加更多上下文并详细描述用例。
  • 我认为你在这里走错了方向。您要求的东西非常困难且不是很有用。而且仍然不清楚您将如何知道您需要访问的 getter 和 setter 的名称。如果您以某种方式知道 XML 中的名称,您可能会使用某种Map。为什么需要上课?
  • 这听起来很像XY problem。现在我们知道您想要更改 XML 文档的某些部分,我们可以解决那个问题。很可能,您只想简单地导航 XML Document,或者,如果 XML 非常大,请使用 XSLTtransform
  • 即使你使用反射,你怎么知道调用哪些方法呢?您如何知道 get-methods 返回什么数据,或者将什么数据传递给 set-method?我认为你的设计有缺陷。您无法合理地告诉人们“发送您想要的任何东西,我会弄清楚的。”你需要定义一个特定的结构,你需要要求其他人遵守它。这就是存在公共方法的原因。这就是 XML 模式存在的原因。如果没有明确定义的通信合同,您最多只能进行不可靠、不可靠的猜测。

标签: java xml


【解决方案1】:

免去您的麻烦:手动创建您的 POJO,并使用 JAXB 将相关的 XML 文件处理到您的 POJO 实例中。有关示例和参考链接,请参阅 this question

【讨论】:

    【解决方案2】:

    让我们从第二个 XML 示例开始,顺便说一句,这与第一个有很大不同...

    又来了(在编辑的情况下,我向 XML 添加了值):

    <data>
        <data_member name="name" type="String">foo</data_member>
        <data_member name="id" type="int">42</data_member>
    </data>
    

    正如 RealSkeptic 在评论中提到的,您可以使用地图:

    import java.util.HashMap;
    import java.util.Map;
    
    public class DataHolder {
    
        private Map<String, Integer> ints = new HashMap<>();
        private Map<String, String> strings = new HashMap<>();
    
        public int getInt(String fieldName) {
            return ints.get(fieldName);
        }
    
        public void setInt(String fieldName, int value) {
            ints.put(fieldName, value);
        }
    
        public String getString(String fieldName) {
            return strings.get(fieldName);
        }
    
        public void setString(String fieldName, String value) {
            strings.put(fieldName, value);
        }
    
    }
    

    我强烈建议只使用一些众所周知的类型:primitives + String 一开始似乎是合理的。不要使用对象,使用它总是很痛苦,在某些时候我需要将它转换为特定的东西。

    但如果我是您的 API 的用户,我会创建包装类以更方便的方式使用它:

    public class DataHolderNameAndIdWrapper {
    
        private DataHolder dataHolder;
    
        public void setDataHolder(DataHolder dataHolder) {
            this.dataHolder = dataHolder;
        }
    
        public String getName() {
            return dataHolder.getString("name");
        }
        public void setName(String name) {
            dataHolder.setString("name", name);
        }
        public Integer getId() {
            return dataHolder.getInt("id");
        }
        public void setId(Integer id) {
            dataHolder.setInt("id", id);
        }
    
    }
    

    因为我作为消费者我想知道我在处理什么,我个人不同意你的评论“人们可以为同样的东西创建一个比编码更容易的 XML”,如你所见,讨论时间更长,然后正确实施...

    还有一些问题

    • 您希望名称区分大小写吗?
    • 如果不设置会怎样?

    虽然 java 区分大小写,但对于上面的用法,我会将字段名称转换为小写。如果不存在,地图将返回空值。我会再次返回空字符串 "" 或 0。

    【讨论】:

      猜你喜欢
      • 2017-08-20
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 2020-07-19
      • 2022-12-18
      • 1970-01-01
      • 2020-07-22
      相关资源
      最近更新 更多