xPath检索多个值

时间:2016-02-29 22:25:38

标签: xml xpath nodelist

我有一个巨大的xml,我需要找到支付金额并对应billID。

我只是想出了如何选择正确的数量(使用CellText ='数量'定位距细胞2个细胞)。我可以打印这个,它可以工作。

现在我还需要打印相应的billID。我该怎么做?

这是我正在使用的XML类型的示例:

<Section>
<Item>
    <TableRow>
        <Cell>
           <RowNo>4</RowNo>
           <CellColNo>1</CellColNo>
           <CellText>amount</CellText>
           <CellAttribute/>
        </Cell>
        <Cell>
           <RowNo>4</RowNo>
           <CellColNo>2</CellColNo>
           <CellText/>
           <CellAttribute/>
        </Cell>
        <Cell>
           <RowNo>4</RowNo>
           <CellColNo>3</CellColNo>
           <CellText>138</CellText>
           <CellAttribute/>
        </Cell>
    </TableRow>
</Item>
<Item>
    <BillID>123456</BillID>
</Item>
</Section>
<Section>
...
</Section>

这是我的代码,我需要添加billID也应该打印

XPath xPath =  XPathFactory.newInstance().newXPath();
String exprString = "//TableRow/Cell[CellText='amount:']/following-sibling::cell[2]CellText/text()";
XPathExpression expr = xPath.compile(exprString);

    Object result = expr.evaluate(doc, XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;
    for (int j = 0; j < nodes.getLength(); j++) {
        System.out.println(nodes.item(j).getNodeValue());
    }

(我知道XML没有意义,它只是为了说明格式。还有几个&#34;章节&#34;,所以我需要确保选择正确的!)。提前谢谢!

2 个答案:

答案 0 :(得分:1)

如果您想同时获得两个String,则可以使用以下XPath表达式应用节点统一运算符|相对于假设的root节点:

/root/Section/Item/TableRow/Cell/CellText[text()='amount']/parent::Cell/following-sibling::Cell[2]/CellText/text() | /root/Section/Item/BillID/text()

可以检查here at XPathFiddle。 这导致

  

138
  123456

答案 1 :(得分:0)

这个代码片段可以做到。从您选择金额的节点中,找到祖先Item节点,转到下一个兄弟并选择BillID文本。一旦选择了金额,它将使用以下XPath:

ancestor::Item[1]/following-sibling::Item[1]/BillID/text()
import java.io.StringReader;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;

public class GetTheBillId {
    private static final String xml1=
"<root>"+
"<Item>"+
"    <TableRow>"+
"        <Cell>"+
"           <RowNo>4</RowNo>"+
"           <CellColNo>1</CellColNo>"+
"           <CellText>amount</CellText>"+
"           <CellAttribute/>"+
"        </Cell>"+
"        <Cell>"+
"           <RowNo>4</RowNo>"+
"           <CellColNo>2</CellColNo>"+
"           <CellText/>"+
"           <CellAttribute/>"+
"        </Cell>"+
"        <Cell>"+
"           <RowNo>4</RowNo>"+
"           <CellColNo>3</CellColNo>"+
"           <CellText>138</CellText>"+
"           <CellAttribute/>"+
"        </Cell>"+
"    </TableRow>"+
"</Item>"+
"<Item>"+
"    <BillID>123456</BillID>"+
"</Item>"+
"</root>";

    private static final String xpathExpr1=
"//TableRow/Cell[CellText='amount']/following-sibling::Cell[2]/CellText/text()";

    private static final String xpathExpr2=
"ancestor::Item[1]/following-sibling::Item[1]/BillID/text()";   

    public static void main(String[] args) {
        try {
            XPath xpath = XPathFactory.newInstance().newXPath();
            XPathExpression expr1 = xpath.compile(xpathExpr1);
            XPathExpression expr2 = xpath.compile(xpathExpr2);
            NodeList nodeList = (NodeList) expr1.evaluate(new InputSource(new StringReader(xml1)),XPathConstants.NODESET);
            StringBuilder sb = new StringBuilder();
            for( int i = 0; i != nodeList.getLength(); ++i ) {
                Node n = (Node) nodeList.item(i);
                sb.append( "Amount=" ).append(n.getNodeValue());

                Node billId = (Node) expr2.evaluate(n,XPathConstants.NODE); // search for Bill ID
                sb.append("; BillId=").append(billId.getNodeValue());
                sb.append(System.lineSeparator());
            }
            System.out.println(sb.toString());
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
    }
}

输出:

Amount=138; BillId=123456