【问题标题】:Parsing child node with own namespace in DOM4j with Java使用Java在DOM4j中解析具有自己命名空间的子节点
【发布时间】:2015-08-03 15:44:34
【问题描述】:

我希望有人可以帮助修复我的 foobar。我已经在 DOM4j 解析器上工作了大约一个月,以使用 XPATH 从 XML 文件中提取 500 多个数据元素。不幸的是,我使用一个旧的测试文件作为模型来创建我的代码,并且在插入生产文件后才发现我的方式错误。这是我的代码的一个小示例。正如您从 Hashmap 中看到的,在完整的 XML 中使用了几个命名空间。我将代码缩减为仅提取 3 个元素。

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

public class CLOBTest {

public static void main(String[] args) {
      try {
         File inputFile = new File("C:/test.xml");
         //File inputFile = new File("C:/test1.xml");
         SAXReader reader = new SAXReader();
         Document document = reader.read( inputFile );

         Map<String, String> map = new HashMap<String, String>();

         map.put("exch", "http://at.dsh.cms.gov/exchange/1.0");
         map.put("ext", "http://at.dsh.cms.gov/extension/1.0");
         map.put("hix-core", "http://hix.cms.gov/0.1/hix-core");
         map.put("hix-ee", "http://hix.cms.gov/0.1/hix-ee");
         map.put("hix-pm", "http://hix.cms.gov/0.1/hix-pm");
         map.put("nc", "http://niem.gov/niem/niem-core/2.0");
         map.put("niem-core", "http://niem.gov/niem/niem-core/2.0");
         map.put("s", "http://niem.gov/niem/structures/2.0");
         map.put("scr", "http://niem.gov/niem/domains/screening/2.1");
         map.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");


         XPath Request = DocumentHelper.createXPath("//exch:AccountTransferRequest");
         Request.setNamespaceURIs(map);

         Node request =  Request.selectSingleNode(document);

         System.out.println("  ID:        \t" + request.valueOf("ext:TransferHeader/ext:TransferActivity/niem-core:ActivityIdentification/niem-core:IdentificationID")); 
         System.out.println("  First Name:\t" + request.valueOf("hix-core:Person/niem-core:PersonName/niem-core:PersonGivenName")); 
         System.out.println("  Last Name: \t" + request.valueOf("hix-core:Person/niem-core:PersonName/niem-core:PersonSurName")); 

      } catch (DocumentException e) {
         e.printStackTrace();
      }
   }
}

示例 XML 文件 (test.xml) 给出了正确的结果:

ID:         XXX012345
First Name: gina
Last Name:  davis

test.xml

 <H15>
 <requestMSG>
 <exch:AccountTransferRequest xmlns:exch="http://at.dsh.cms.gov/exchange/1.0" xmlns:hix-core="http://hix.cms.gov/0.1/hix-core" xmlns:niem-core="http://niem.gov/niem/niem-core/2.0" xmlns:s="http://niem.gov/niem/structures/2.0" xmlns:ext="http://at.dsh.cms.gov/extension/1.0" ext:atVersionText="2.3">
 <ext:TransferHeader>
 <ext:TransferActivity>
 <niem-core:ActivityIdentification xmlns:niem-core="http://niem.gov/niem/niem-core/2.0">
 <niem-core:IdentificationID>XXX012345</niem-core:IdentificationID>
 </niem-core:ActivityIdentification>
 </ext:TransferActivity>
 </ext:TransferHeader>
 <hix-core:Person xmlns:hix-core="http://hix.cms.gov/0.1/hix-core" xmlns:s="http://niem.gov/niem/structures/2.0" s:id="Mom">
 <niem-core:PersonName xmlns:niem-core="http://niem.gov/niem/niem-core/2.0">
 <niem-core:PersonGivenName>gina</niem-core:PersonGivenName>
 <niem-core:PersonSurName>davis</niem-core:PersonSurName>
 </niem-core:PersonName>
 </hix-core:Person>
 </exch:AccountTransferRequest>
 </requestMSG>
 </H15>

但是,如果元素 exch:AccountTransferRequest 不包含所有命名空间引用,我会在子节点上收到 Unbounded prefix 错误。我假设对 Request XPath 的 Hashmap 分配已经处理了所有的前缀绑定。在对 exch:AccountTransferRequest 元素中没有完整 URI 的生产文件 (test1.xml) 进行尝试后,我意识到我错了。

test1.xml

 <H15>
 <requestMSG>
 <exch:AccountTransferRequest xmlns:exch="http://at.dsh.cms.gov/exchange/1.0" xmlns:ext="http://at.dsh.cms.gov/extension/1.0" ext:atVersionText="2.3">
 <ext:TransferHeader>
 <ext:TransferActivity>
 <niem-core:ActivityIdentification xmlns:niem-core="http://niem.gov/niem/niem-core/2.0">
 <niem-core:IdentificationID>XXX012345</niem-core:IdentificationID>
 </niem-core:ActivityIdentification>
 </ext:TransferActivity>
 </ext:TransferHeader>
 <hix-core:Person xmlns:hix-core="http://hix.cms.gov/0.1/hix-core" xmlns:s="http://niem.gov/niem/structures/2.0" s:id="Mom">
 <niem-core:PersonName xmlns:niem-core="http://niem.gov/niem/niem-core/2.0">
 <niem-core:PersonGivenName>gina</niem-core:PersonGivenName>
 <niem-core:PersonSurName>davis</niem-core:PersonSurName>
 </niem-core:PersonName>
 </hix-core:Person>
 </exch:AccountTransferRequest>
 </requestMSG>
 </H15>

test1.xml 结果:

Exception in thread "main" org.dom4j.XPathException: Exception occurred evaluting XPath: ext:TransferHeader/ext:TransferActivity/niem-core:ActivityIdentification/niem-core:IdentificationID. Exception: XPath expression uses unbound namespace prefix niem-core
    at org.dom4j.xpath.DefaultXPath.handleJaxenException(DefaultXPath.java:374)
    at org.dom4j.xpath.DefaultXPath.valueOf(DefaultXPath.java:185)
    at org.dom4j.tree.AbstractNode.valueOf(AbstractNode.java:191)
    at CLOBTest.main(CLOBTest.java:41)

现在,如何提取具有自己命名空间的子节点的值?有没有办法在仍然通过请求节点的同时做到这一点?如果可能的话,我想挽救我的一些努力。

【问题讨论】:

    标签: xpath namespaces dom4j


    【解决方案1】:

    您似乎需要创建更多 XPath 对象,并且每次都设置命名空间上下文,例如

         XPath Request = DocumentHelper.createXPath("//exch:AccountTransferRequest");
         Request.setNamespaceURIs(map);
    
         Node request =  Request.selectSingleNode(document);
    
         XPath idRequest = DocumentHelper.createXPath("ext:TransferHeader/ext:TransferActivity/niem-core:ActivityIdentification/niem-core:IdentificationID");
         idRequest.setNamespaceURIs(map);
    
         System.out.println("  ID:        \t" + idRequest.selectSingleNode(request).getText()); 
    

    【讨论】:

    • 太棒了。这应该让我可以挽救很多,但仍然需要大量的重新编码。我会让你知道结果如何。非常感谢。
    • 我已经尝试这个解决方案一个多星期了。我通过了一些课程,但现在我遇到了障碍。当我有一个从一个节点开始但引用另一个节点的 XPATH 时,我无法提前绑定第二个节点的命名空间。有没有办法从 XML 文档中选择一个节点,向它添加所有可能的命名空间属性,然后将它作为节点传递给另一个类,命名空间属性仍然附加?我需要从节点转换到元素还是反之亦然?
    【解决方案2】:

    好的,想通了。只需要将请求节点转换为一个元素并添加所有命名空间。一旦我在输出中使用了该元素,整个文档就会识别它们。

             Element test = (Element) request;
             test.addNamespace("exch", "http://at.dsh.cms.gov/exchange/1.0");
             test.addNamespace("ext", "http://at.dsh.cms.gov/extension/1.0");
             test.addNamespace("hix-core", "http://hix.cms.gov/0.1/hix-core");
             test.addNamespace("hix-ee", "http://hix.cms.gov/0.1/hix-ee");
             test.addNamespace("hix-pm", "http://hix.cms.gov/0.1/hix-pm");
             test.addNamespace("nc", "http://niem.gov/niem/niem-core/2.0");
             test.addNamespace("niem-core", "http://niem.gov/niem/niem-core/2.0");
             test.addNamespace("s", "http://niem.gov/niem/structures/2.0");
             test.addNamespace("scr", "http://niem.gov/niem/domains/screening/2.1");
             test.addNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    
             System.out.println("  ID:                                             \t"+test.valueOf("ext:TransferHeader/ext:TransferActivity/niem-core:ActivityIdentification/niem-core:IdentificationID")); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-09
      • 1970-01-01
      • 1970-01-01
      • 2013-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-07
      相关资源
      最近更新 更多