假设我的XML树中有四个级别,其中级别3可以有相同的子级 - 两次,即 在以下XML中:
<Game>
<Round>
<roundNumber>1</roundNumber>
<Door>
<doorName>abd11</doorName>
<Value>
<xVal1>0</xVal1>
<xVal2>25</xVal2>
<pVal>0.31</pVal>
</Value>
<Value>
<xVal1>25</xVal1>
<xVal2>50</xVal2>
<pVal>0.04</pVal>
</Value>
<Value>
<xVal1>50</xVal1>
<xVal2>75</xVal2>
<pVal>0.19</pVal>
</Value>
<Value>
<xVal1>75</xVal1>
<xVal2>100</xVal2>
<pVal>0.46</pVal>
</Value>
</Door>
<Door>
<doorName>vvv1133</doorName>
<Value>
<xVal1>60</xVal1>
<xVal2>62</xVal2>
<pVal>1.0</pVal>
</Value>
</Door>
</Round>
<Round>
<roundNumber>2</roundNumber>
<Door>
<doorName>eee</doorName>
<Value>
<xVal1>0</xVal1>
<xVal2>-25</xVal2>
<pVal>0.31</pVal>
</Value>
<Value>
<xVal1>-25</xVal1>
<xVal2>-50</xVal2>
<pVal>0.04</pVal>
</Value>
<Value>
<xVal1>-50</xVal1>
<xVal2>-75</xVal2>
<pVal>0.19</pVal>
</Value>
<Value>
<xVal1>-75</xVal1>
<xVal2>-100</xVal2>
<pVal>0.46</pVal>
</Value>
</Door>
<Door>
<doorName>cc</doorName>
<Value>
<xVal1>-60</xVal1>
<xVal2>-62</xVal2>
<pVal>0.3</pVal>
</Value>
<Value>
<xVal1>-70</xVal1>
<xVal2>-78</xVal2>
<pVal>0.7</pVal>
</Value>
</Door>
</Round>
</Game>
每个Doors
我有两个Round
,那么问题是,使用Dom
或Sax
(或Jdom,如果它有帮助)可以
我迭代我的树并获得每个级别的数据?
此刻,我“降低”并获得了回合,在这里:
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse (new File("input.xml"));
// normalize text representation
doc.getDocumentElement ().normalize ();
System.out.println ("Root element of the doc is " + // would produce Game
doc.getDocumentElement().getNodeName());
NodeList roundNodes = doc.getElementsByTagName("Round"); // roundNodes are the Rounds
int totalNodes = roundNodes.getLength(); // 2 by the example
System.out.println("Total number of Rounds are : " + totalNodes);
for (int i = 0; i < roundNodes.getLength() ; i++)
{
Node node = roundNodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
Element element = (Element)node;
NodeList firstDoorList = element.getElementsByTagName("Door");
Element firstDoorElement = (Element)firstDoorList.item(0);
NodeList textFNList = firstDoorElement.getChildNodes();
System.out.println("First Door : " + ((Node)textFNList.item(0)).getNodeValue().trim());
}
}
但似乎迭代的代码很多。
是否有一种简单的方法来提取该XML的数据?假设我每轮有2个门,有些轮数。
谢谢
答案 0 :(得分:2)
解析这样的内容是我写SJXP的原因之一 - 我知道,我知道“哦,上帝,不是另一个家庭酿造的图书馆!”,但不要绝望,这很容易 - to-use库构建在STAX解析器规范的ontop上,因此您不会获得使用DOM轻松完成的开销。我把它作为手写源解析器(RDF,RSS,ATOM)一年多来的结果,并且意识到我的工作越复杂,它就越相似,所以我把核心租户简化为一个,简单快速的库(开销小于SAX解析器 - 它也可以在Android上运行,没有添加依赖项)。
库的要点是定义一系列规则,这些规则针对您想要的XML中的所有元素。鉴于您要解析的所有XML数据都是CHARACTER数据(不是标记内部的属性数据),您可以定义一系列字符规则,如下所示:
IRule roundNumRule = new DefaultRule(Type.CHARACTER, "/Game/Round/roundNumber") {
@Override
public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
System.out.println("Round Parsed: " + text);
}
}
IRule doorNameRule = new DefaultRule(Type.CHARACTER, "/Game/Round/Door/doorName") {
@Override
public void handleParsedCharacters(XMLParser parser, String text, Object userObject) {
System.out.println("Door Name: " + text);
}
}
......依此类推 - 其他规则的路径如下所示:
在你掌握了所有规则之后,你会像这样创建一个XMLParser instance,给它你创建的所有规则:
XMLParser parser = new XMLParser(roundNumRule, doorNameRule, <more rules>);
然后使用它来解析XML,方法是通过parse methods之一提供代表XML流的任何有效 InputStream 实例。
您可以安全地重复使用XMLParser实例(不是同时在单独的线程中)。
你需要跟踪你的状态,因为你知道你正在为哪个roundNumber加载门值以及用哪些值填充哪个门,但这很容易做 - 只需创建简单的Java POJO表示您的结构并将它们存储在ArrayList中,例如:
List<Round> roundList = new ArrayList<Round)();
说你的“回合”POJO看起来像这样:
public class Round {
public int number;
public List<Door> doorList;
}
你的门POJO看起来像是:
public class Door {
public String name;
public int xVal1;
public int yVal2;
public double pVal;
}
顶级 roundList 将代表已解析值的根,您可以将其直接传递给解析操作;这是您在SJXP Javadocs中引用的 userObject 。
当规则匹配时会发生什么,它会将userObject传递给规则,这样您就可以访问传入的列表。
对于roundNumRule - 您将创建一个新的Round POJO,为其指定roundNumber值并将其添加到列表中。
对于doorNameRule - 你将从列表中拉出最后一轮,向它添加一个新的POJO并为其指定名称。
等等......
我希望有所帮助!