使用XPath循环遍历XML String - Java

时间:2014-02-04 13:25:59

标签: java xml xpath

我有一个函数我想循环遍历xml并拉出某些标签。

我的xml看起来像这样:

<Report_Data>
    <Report_Entry>
        <Company>Test</Company>
        <Name>Test Name</Name>
        <Division>Test Division</Division>
    </Report_Entry>
    <Report_Entry>
        <Company>Test 2</Company>
        <Name>Test Name 2</Name>
        <Division>Test Division 2</Division>
    </Report_Entry>
    <Report_Entry>
        <Company>Test 3</Company>
        <Name>Test Name 3</Name>
        <Division>Test Division 3</Division>
    </Report_Entry>
</Report_Data>

这是我的循环代码:

String comp, name, div, nodeName, NodeValue;
Node node;
try
{
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();

InputSource source = new InputSource(new StringReader(coaFULL));
Document doc2 = (Document) xpath.evaluate("/", source, XPathConstants.NODE);

NodeList nodeList = (NodeList) xpath.compile("/Report_Data/Report_Entry").evaluate(doc2, XPathConstants.NODESET);
System.out.println("NODE LIST LENGTH =" + nodeList.getLength());

String nodeName, nodeValue = "";
Node node;

for(int i = 0; i < nodeList.getLength(); i++)
{
    node = nodeList.item(i);
    node = nodeList.item(i).getFirstChild();
    nodeName = node.getNodeName();
    nodeValue = node.getChildNodes().item( 0 ).getNodeValue();

    if(nodeName.equals("Company"))
    {
        comp = nodeValue;
    }
    else if( nodeName.equals("Name"))
    {
        name = nodeValue;
    }
    else if(nodeName.equals("Division"))
    {
        div = nodeValue;
    }
    System.out.println("COMPANY = " + comp);
    System.out.println("NAME = " + name);
    System.out.println("DIVISION = " + div);
}

当我运行我的代码时,只有第一个值(公司)获得实际值,其他一切都是空白的。我还尝试在每个if语句中添加node = nodeList.item(i).getNextSibling();以获取下一个节点,但这不起作用。

我的nodeList确实包含超过1000的项目。这句话是否有问题:NodeList nodeList = (NodeList) xpath.compile("/Report_Data/Report_Entry").evaluate(doc2, XPathConstants.NODESET);

应该是:NodeList nodeList = (NodeList) xpath.compile("/Report_Data/Report_Entry/*").evaluate(doc2, XPathConstants.NODESET);

我在最后使用/*尝试了它,但这导致nodeList中包含每个节点。我想确保当我获取Report_Entry节点时,我将字符串变量设置为彼此对应的正确值。

=============================================== ===========

解决方案:这很难看,但我的解决方案是只使用一个循环并使用带有硬编码值的第二个子节点列表:

for(int i = 0; i < nodeList.getLength(); i++)
{
    node = nodeList.item(i);
    tempList = node.getChildNodes();
    System.out.println("TEMP LIST LENGTH =" + tempList.getLength());
    comp = tempList.item(0).getTextContent();
    name = tempList.item(1).getTextContent();
    div = tempList.item(2).getTextContent();
}

感谢@hage的帮助。

1 个答案:

答案 0 :(得分:1)

也许是因为你的node只是第一个孩子?

node = nodeList.item(i);
node = nodeList.item(i).getFirstChild();

我猜nodeList.item(i)会给你Report_Entry,他们的第一个孩子就是Company

您需要遍历Company条目的所有子项

编辑(关于您的修改):

tempList.item(x)CompanyName,然后是Division。当你得到这个孩子的第一个孩子时,你就在文本节点(实际内容)。并且因为您尝试获取此节点的名称,所以获得#text输出(see this)。

要获取节点的名称和值,请尝试此(未经测试)

nodeName = tempList.item(x).getNodeName();
nodeValue = tempList.item(x).getTextContent();