【问题标题】:Java: Get properties of an object by parsing XML-fileJava:通过解析 XML 文件获取对象的属性
【发布时间】:2013-09-29 19:24:30
【问题描述】:

我有一个关于 XML 和解析它的问题。我使用 JDOM 来解析我的 XML 文件,但我遇到了一个小问题。

我的 XML 文件示例如下所示:

 <IO name="Bus" type="Class">
    <ResourceAttribute name="Bandwidth" type="KiloBitPerSecond" value="50" />
 </IO>

Bus 是类 IO 的对象实例。该对象获得了名称和类型属性。此外,它还有一些属性,例如示例中的属性带宽,值为 50,数据类型为 KiloBitPerSecond。

所以当我想循环文件时:

    for(Element packages : listPackages)
        {
                Map<String, Values> valueMap = new HashMap<String, Values>();
                List<Element> objectInstanceList = packages.getChildren();

                for(Element objects : objectInstanceList) 
                {
                    List<Element> listObjectClasses = objects.getChildren();

                    for(Element classes : listObjectClasses) 
                    {
                    List<Element> listObjectAttributes = classes.getChildren();

                        for(Element objectAttributes : listObjectAttributes)
                        {
                            List<Attribute> listAttributes = objectAttributes.getAttributes();

                            for(Attribute attributes : listAttributes)
                            {

                            String name = attributes.getName();
                            String value = attributes.getValue();
                            AttributeType datatype = attributes.getAttributeType();
                            Values v = new Values(name, datatype, value);
                            valueMap.put(classes.getName(), v);
                            System.out.println(name + ":" + value);
                            }

                        }
                    }
                                        }
                //System.out.println(valueMap);
         }

values 是一个定义对象属性的类:

public class Values{
 private String name;
 //private AttributeType datatype;
 private String value;

这就是本准则的其余部分。我有两个与此相关的问题。目前第一个优先级更高。

  1. 如何获取对象的值(Attribute.Name = Bandwidth; Attribute.Value = 50) ?我反而得到了

    名称:巴士 类型:类

    我想过一个额外的for循环,但是JDOM类属性没有一个叫做getAttributes()的方法。

  2. 这只是第二个优先事项,因为没有问题 1,我无法走得更远。正如您在示例中看到的,一个属性有 3 个属性,名称、类型和值。我怎样才能提取样本的三重放置。 JDOM 似乎只知道 Attribute、name 和 value 的 2 个属性。

非常感谢,希望我能够表达自己。

编辑:在其中添加了一个额外的 for 循环,所以现在的输出是:

name:Bandwidth
type:KiloBitPerSecond
value:50

这意味着 name 是该属性的名称,而 value 是 name 的值。不知道。至少问题一现在更清楚了,我可以尝试处理 2,但新信息使我更清楚 2。

【问题讨论】:

  • 你应该使用递归来解析你的xml
  • 值应该是符合java命名约定的值,类应该以大写字母开头
  • 也许你对“ResourceAttribute”这个名字感到困惑?这是一个 XML 元素(而不是 XML 属性)。当然,属性没有属性。
  • @Seelenvirtuose 是的,你是对的,有点困惑,但我自己已经修好了,谢谢。
  • 如果这是我建议使用 JAXB 的新代码,那么您不必进行任何解析。只需在您的对象中添加一些注释并调用几行代码即可将 XML 转换为 Java 对象。如果您必须使用 jdom,请忽略它。

标签: java xml xml-parsing jdom


【解决方案1】:

在 xml 中,elements 的开始标签位于 &lt;&gt;(或 /&gt;)之间,&lt; 之后是元素的名称,然后是 attributes 的列表格式为name="value"。一个元素可以用/&gt;或结束标签&lt;/[element name]&gt;关闭

最好使用递归来解析您的 xml,而不是使用可读性差/可维护性差的嵌套 for 循环。

这是它的样子:

@Test
public void parseXmlRec() throws JDOMException, IOException {
    String xml = "<root>"
            + "<Package>"
            + "<IO name=\"Bus\" type=\"Class\">\r\n" + 
            "    <ResourceAttribute name=\"Bandwidth\" type=\"KiloBitPerSecond\" value=\"50\" />\r\n" + 
            " </IO>"
            + "</Package>"
            + "</root>";
    InputStream is = new ByteArrayInputStream(xml.getBytes());
    SAXBuilder sb = new SAXBuilder();
    Document document = sb.build(is);
    is.close();

    Element root = document.getRootElement();
    List<Element> children = root.getChildren();
    for(Element element : children) {
        parseelement(element);
    }
}

private void parseelement(Element element) {
    System.out.println("Element:" + element.getName());
    String name = element.getAttributeValue("name");
    if(name != null) {
        System.out.println("name: " + name);    
    }
    String type = element.getAttributeValue("type");
    if(type != null) {
        System.out.println("type: " + type);
    }
    String value = element.getAttributeValue("value");
    if(value != null) {
        System.out.println("value: " + value);
    }
    List<Element> children = element.getChildren();
    if(children != null) {
        for(Element child : children) {
            parseelement(child);
        }
    }
}

这个输出:

Element: Package
Element: IO
name: Bus
type: Class
Element: ResourceAttribute
name: Bandwidth
type: KiloBitPerSecond
value: 50

在解析时,检查每个元素的名称并实例化对应的对象。为此,我建议编写一个单独的方法来处理每个元素。例如:

void parsePackage(Element packageElement) { ... }
parseIO(Element ioElement) { ... }
void parseResourceAttribute(Element resourceAttributeElement) { ... }

【讨论】:

  • 感谢您的回答。您的代码对于任何类型的输入仍然有效吗? XML 样本只是一个单一的行。我的文件包含我的元素和属性,我不知道数字,所以代码必须适合任何类型的输入。 for 循环可能不是那么漂亮,但对于我这个新手来说,实现起来要容易得多。
  • @Alika87 好吧,对于元素是的,但正如你所见,它只检查每个元素的属性 nametypevalue。只需对您的输入文档运行它并查看输出。您需要知道 xml 文档的结构,并为每个元素创建一个单独的方法作为解析它的方法。在每个方法中循环子元素并为每个元素调用相应的方法。
猜你喜欢
  • 2021-08-29
  • 1970-01-01
  • 2012-06-08
  • 1970-01-01
  • 2017-05-02
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 2010-09-22
相关资源
最近更新 更多