Xpath.evaluate()方法不会在JAVA上返回任何值

时间:2013-06-24 10:23:35

标签: java xml xpath evaluate

我有一个这样的XML示例文件:

<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2011 rel. 2 (x64) (http://www.altova.com)-->
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.05"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.05 file://BE-FILE01/tverschu$/SR%20(Standards%20Release)/SR2013/ISO/Payments%20Initiation/SR2013_MX_Schemas_PaymentsInitiation/pain.001.001.05.xsd">
<CstmrCdtTrfInitn>
    <GrpHdr>
        <MsgId>ABC/120928/CCT001</MsgId>
        <CreDtTm>2012-09-28T14:07:00</CreDtTm>
        <NbOfTxs>3</NbOfTxs>
        <CtrlSum>11500000</CtrlSum>
        <InitgPty>
            <Nm>ABC Corporation</Nm>
            <PstlAdr>
                <StrtNm>Times Square</StrtNm>
                <BldgNb>7</BldgNb>
                <PstCd>NY 10036</PstCd>
                <TwnNm>New York</TwnNm>
                <Ctry>US</Ctry>
            </PstlAdr>
        </InitgPty>
    </GrpHdr>
    <PmtInf>
        <PmtInfId>ABC/086</PmtInfId>
        <PmtMtd>TRF</PmtMtd>
        <BtchBookg>false</BtchBookg>
        <ReqdExctnDt>2012-09-29</ReqdExctnDt>
        <Dbtr>
            <Nm>ABC Corporation</Nm>
            <PstlAdr>
                <StrtNm>Times Square</StrtNm>
                <BldgNb>7</BldgNb>
                <PstCd>NY 10036</PstCd>
                <TwnNm>New York</TwnNm>
                <Ctry>US</Ctry>
            </PstlAdr>
        </Dbtr>
        <DbtrAcct>
            <Id>
                <Othr>
                    <Id>00125574999</Id>
                </Othr>
            </Id>
        </DbtrAcct>
        <DbtrAgt>
            <FinInstnId>
                <BICFI>BBBBUS33</BICFI>
            </FinInstnId>
        </DbtrAgt>
        <CdtTrfTxInf>
            <PmtId>
                <InstrId>ABC/120928/CCT001/01</InstrId>
                <EndToEndId>ABC/4562/2012-09-08</EndToEndId>
            </PmtId>
            <Amt>
                <InstdAmt Ccy="JPY">10000000</InstdAmt>
            </Amt>
            <ChrgBr>SHAR</ChrgBr>
            <CdtrAgt>
                <FinInstnId>
                    <BICFI>AAAAGB2L</BICFI>
                </FinInstnId>
            </CdtrAgt>
            <Cdtr>
                <Nm>DEF Electronics</Nm>
                <PstlAdr>
                    <AdrLine>Corn Exchange 5th Floor</AdrLine>
                    <AdrLine>Mark Lane 55</AdrLine>
                    <AdrLine>EC3R7NE London</AdrLine>
                    <AdrLine>GB</AdrLine>
                </PstlAdr>
            </Cdtr>
            <CdtrAcct>
                <Id>
                    <Othr>
                        <Id>23683707994125</Id>
                    </Othr>
                </Id>
            </CdtrAcct>
            <Purp>
                <Cd>GDDS</Cd>
            </Purp>
            <RmtInf>
                <Strd>
                    <RfrdDocInf>
                        <Tp>
                            <CdOrPrtry>
                                <Cd>CINV</Cd>
                            </CdOrPrtry>
                        </Tp>
                        <Nb>4562</Nb>
                        <RltdDt>2012-09-08</RltdDt>
                    </RfrdDocInf>
                </Strd>
            </RmtInf>
        </CdtTrfTxInf>
        <CdtTrfTxInf>
            <PmtId>
                <InstrId>ABC/120928/CCT001/2</InstrId>
                <EndToEndId>ABC/ABC-13679/2012-09-15</EndToEndId>
            </PmtId>
            <Amt>
                <InstdAmt Ccy="EUR">500000</InstdAmt>
            </Amt>
            <ChrgBr>CRED</ChrgBr>
            <CdtrAgt>
                <FinInstnId>
                    <BICFI>DDDDBEBB</BICFI>
                </FinInstnId>
            </CdtrAgt>
            <Cdtr>
                <Nm>GHI Semiconductors</Nm>
                <PstlAdr>
                    <StrtNm>Avenue Brugmann</StrtNm>
                    <BldgNb>415</BldgNb>
                    <PstCd>1180</PstCd>
                    <TwnNm>Brussels</TwnNm>
                    <Ctry>BE</Ctry>
                </PstlAdr>
            </Cdtr>
            <CdtrAcct>
                <Id>
                    <IBAN>BE30001216371411</IBAN>
                </Id>
            </CdtrAcct>
            <InstrForCdtrAgt>
                <Cd>PHOB</Cd>
                <InstrInf>+32/2/2222222</InstrInf>
            </InstrForCdtrAgt>
            <Purp>
                <Cd>GDDS</Cd>
            </Purp>
            <RmtInf>
                <Strd>
                    <RfrdDocInf>
                        <Tp>
                            <CdOrPrtry>
                                <Cd>CINV</Cd>
                            </CdOrPrtry>
                        </Tp>
                        <Nb>ABC-13679</Nb>
                        <RltdDt>2012-09-15</RltdDt>
                    </RfrdDocInf>
                </Strd>
            </RmtInf>
        </CdtTrfTxInf>
        <CdtTrfTxInf>
            <PmtId>
                <InstrId>ABC/120928/CCT001/3</InstrId>
                <EndToEndId>ABC/987-AC/2012-09-27</EndToEndId>
            </PmtId>
            <Amt>
                <InstdAmt Ccy="USD">1000000</InstdAmt>
            </Amt>
            <ChrgBr>SHAR</ChrgBr>
            <CdtrAgt>
                <FinInstnId>
                    <BICFI>BBBBUS66</BICFI>
                </FinInstnId>
            </CdtrAgt>
            <Cdtr>
                <Nm>ABC Corporation</Nm>
                <PstlAdr>
                    <Dept>Treasury department</Dept>
                    <StrtNm>Bush Street</StrtNm>
                    <BldgNb>13</BldgNb>
                    <PstCd>CA 94108</PstCd>
                    <TwnNm>San Francisco</TwnNm>
                    <Ctry>US</Ctry>
                </PstlAdr>
            </Cdtr>
            <CdtrAcct>
                <Id>
                    <Othr>
                        <Id>4895623</Id>
                    </Othr>
                </Id>
            </CdtrAcct>
            <Purp>
                <Cd>INTC</Cd>
            </Purp>
            <RmtInf>
                <Strd>
                    <RfrdDocInf>
                        <Tp>
                            <CdOrPrtry>
                                <Cd>CINV</Cd>
                            </CdOrPrtry>
                        </Tp>
                        <Nb>987-AC</Nb>
                        <RltdDt>2012-09-27</RltdDt>
                    </RfrdDocInf>
                </Strd>
            </RmtInf>
        </CdtTrfTxInf>
    </PmtInf>
</CstmrCdtTrfInitn>
</Document>

我想从Document标签中检索xmlns属性值。为此,我使用的是xpath的evaluate方法:

            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        InputStream inputStream = new FileInputStream(new File("Business sample 1 pain.001.xml"));
        org.w3c.dom.Document doc = documentBuilderFactory.newDocumentBuilder().parse(inputStream);
        StringWriter stw = new StringWriter();
        Transformer serializer = TransformerFactory.newInstance().newTransformer();
        serializer.transform(new DOMSource(doc), new StreamResult(stw));

        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();


        String xml = stw.toString();

        InputSource xmlsource = new InputSource(new StringReader(xml));

        String value = xpath.evaluate(
            "Document/attribute::xmlns", xmlsource);

        System.out.println(value);

此代码将值返回为“”。

我曾尝试过改变:

String value = xpath.evaluate("Document/attribute::xmlns", xmlsource);

有:

String value = xpath.evaluate("Document/CstmrCdtTrfInitn/GrpHdr/MsgId", xmlsource);

进行测试,我得到相同的回报“”。

我做错了什么?

我需要的回报是pain.001.001.05,但是如果我得到所有字符串urn:iso:std:iso:20022:tech:xsd:pain.001.001.05,它对我也很有用。

提前谢谢。

3 个答案:

答案 0 :(得分:3)

xmlns="..."声明意味着Document元素(及其所有后代)位于指定的命名空间中,因此您不会获得/Document的任何匹配,因为它只选择元素名称Document不在命名空间中 - 并且您不能为正确的命名空间声明前缀,因为“正确的命名空间”是您首先想要找到的内容!

但是你不需要XPath来做到这一点 - 你已经有了

org.w3c.dom.Document doc = documentBuilderFactory.newDocumentBuilder().parse(inputStream);

这是原始文档的非命名空间感知的 DOM树(因为DocumentBuilderFactory默认情况下不支持名称空间),其中xmlns 作为属性处理,因此您可以使用

获取值
String xmlnsVal = doc.getDocumentElement().getAttribute("xmlns");
String lastSegment = xmlnsVal.substring(xmlnsVal.lastIndexOf(':') + 1);
// this is safe even if xmlnsVal doesn't contain any colons - lastIndexOf
// will return -1, so substring(0) is the whole xmlnsVal

如果您在启用名称空间的情况下解析,即您在documentBuilderFactory.setNamespaceAware(true)之前调用了newDocumentBuilder(),那么您可以使用

String xmlnsVal = doc.getDocumentElement().getNamespaceURI();

答案 1 :(得分:1)

我认为"namespace-uri(/*)" XPath将返回URI(完整字符串,不仅仅是在最后:之后)。

答案 2 :(得分:0)

您需要考虑默认的命名空间声明,如How to use XPath on xml docs having default namespace所示。