【问题标题】:Xpath is inconsistent for an xmlXpath 与 xml 不一致
【发布时间】:2019-12-16 21:10:25
【问题描述】:

我有以下xml

<?xml version="1.0" encoding="UTF-8"?>
<qdbapi>
   <action>****</action>
   <errcode>0</errcode>
   <errtext>No error</errtext>
   <qid>****</qid>
   <qname>****</qname>
   <table>
      <fields>
         <field id="19" field_type="text" base_type="text" />
      </fields>
      <records>
         <record>
            <f id="6">1</f>
         </record>
         <record>
            <f id="6">1</f>
         </record>
         <record>
            <f id="6">1</f>
         </record>
      </records>
   </table>
</qdbapi>

我使用 dom4j 从 xml 中提取记录。以下 xpath 有效:

//qdbapi//fields//field

以下路径适用于 //qdbapi/records 但不适用于 //qdbapi//records//record

//qdbapi//records//record

两个 xpath(字段、记录)都可以在 xpath 在线测试器中工作,但不能在代码中。

代码如下:

    XmlByteArrayStream = NewJavaObject("java.io.ByteArrayInputStream", {xmlStringBytes});
    SAXReaderObj = NewJavaObject("org.dom4j.io.SAXReader", {});
    XMLDOMDocObj = JavaCall("org.dom4j.io.SAXReader", SAXReaderObj, "read", { XmlByteArrayStream } );
    SelectedNodes = JavaCall('java.util.ArrayList',XMLDOMDocObj,"selectNodes",{"//qdbapi//records"});
    SelectedNodesSize = JavaCall(null,SelectedNodes,"size",{});
    SelectedRecordElement = JavaCall('java.util.ArrayList',SelectedNodes,"get",{0});
    Log(PolicyName + " " +"QBQueryResult:" +SelectedNodesSize);
    recordSelectedNodeChildElements = JavaCall('java.util.ArrayList',SelectedRecordElement,"selectNodes",{"//record"});
    SelectedNodeChildElementsSize = JavaCall(null,recordSelectedNodeChildElements,"size",{});
    Log(PolicyName + " " +"QBQueryResult:" +SelectedNodeChildElementsSize);//printed size is zero

【问题讨论】:

  • #1:为什么 XPath 使用多个 //? // 将是“文档的根”,使您的 Xpath 跳转到 root->elementlist->back to root->new element list->back to root。没有多个 // 选择一条记录将变为“//qdbapi/records/record”。 (不知道为什么 dom4j 对两个 XPath 的行为如此)
  • 此绝对表达式//qdbapi//records//record//record 绝对表达式不同。两者都从文档根目录开始选择。如果你想从某个上下文节点中获得一个相对表达式,你可能会提供给你的 API,最好.//record

标签: java xpath dom4j


【解决方案1】:

DOM4J 的行为符合预期。这个sn-p:

static String XML =
        "<?xml version='1.0' encoding='UTF-8'?>\n" +
        "<qdbapi>\n" +
        "   <action>****</action>\n" +
        "   <errcode>0</errcode>\n" +
        "   <errtext>No error</errtext>\n" +
        "   <qid>****</qid>\n" +
        "   <qname>****</qname>\n" +
        "   <table>\n" +
        "      <fields>\n" +
        "         <field id='19' field_type='text' base_type='text' />\n" +
        "      </fields>\n" +
        "      <records>\n" +
        "         <record>\n" +
        "            <f id='6'>1</f>\n" +
        "         </record>\n" +
        "         <record>\n" +
        "            <f id='6'>1</f>\n" +
        "         </record>\n" +
        "         <record>\n" +
        "            <f id='6'>1</f>\n" +
        "         </record>\n" +
        "      </records>\n" +
        "   </table>\n" +
        "</qdbapi>";

public static void main(String[] args) throws Exception {
    Document doc = new SAXReader().read(new StringReader(XML));
    doc.selectNodes("//qdbapi//fields/field")
        .forEach((e) -> System.out.println(e.getName()));
    System.out.println();
    doc.selectNodes("//qdbapi//records//record")
        .forEach((e) -> System.out.println(e.getName()));
}

产生以下输出:

field

record
record
record

问题肯定出在您的代码上(顺便说一句,这看起来很奇怪),而不是 DOM4J。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 2014-10-13
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 2011-06-27
    相关资源
    最近更新 更多