【问题标题】:How do I extract data from nested XML using JAVA DOM?如何使用 JAVA DOM 从嵌套 XML 中提取数据?
【发布时间】:2014-04-09 19:36:40
【问题描述】:

我有一个包含多个 .我能够获取和帐户详细信息(,等。我很难获取诸如 card_type、year、month、first_six 等内容。

此文档中有 200 笔交易,因此是循环。

  <transaction href="https://test.com" type="cc">
    <source>subscription</source>
    <created_at type="datetime">2014-03-06T20:59:03Z</created_at>
    <details>
      <account>
        <account_code>234234234</account_code>
        <first_name>asdadad</first_name>
        <last_name>asdadasd3433</last_name>
        <company nil="nil"></company>
        <email>test@gmail.com</email>
        <billing_info type="credit_card">
          <first_name>asdasdasd</first_name>
          <last_name>asdasdasd23434</last_name>
          <address1 nil="nil"></address1>
          <address2 nil="nil"></address2>
          <city nil="nil"></city>
          <state nil="nil"></state>
          <zip nil="nil"></zip>
          <country nil="nil"></country>
          <phone nil="nil"></phone>
          <vat_number nil="nil"></vat_number>
          <card_type>Visa</card_type>
          <year type="integer">2039</year>
          <month type="integer">6</month>
          <first_six>111111</first_six>
          <last_four>9999</last_four>
        </billing_info>
      </account>
    </details>
    <a name="refund" href="https://test.com/refund" method="delete"/>
  </transaction>

我在尝试我的代码时收到此错误:

java.lang.NullPointerException
        at test.test.getTransactions(test.java:288)
        at test.test.main(test.java:53)

这是我正在尝试的:

try {
  NodeList nList2 = eElement.getElementsByTagName("details");
  Node nNode2 = nList2.item(0);
  Element eElement2 = (Element) nNode2;

  //get some other info in try catch blocks here (removed for reading)

  try {
    System.out.println("attempting billing info");
    NodeList nList3 = eElement2.getElementsByTagName("billing_info");
    Node nNode3 = nList3.item(0);
    Element eElement3 = (Element) nNode3;    
    System.out.println("attempting credit_year");
    System.out.println("credit_year: " + eElement3.getElementsByTagName("credit_year").item(0).getTextContent());
  } catch (Exception ex) {
    ex.printStackTrace();
  }

}

【问题讨论】:

    标签: java xml dom


    【解决方案1】:

    这里有一些代码可以指导您使用 DOM 解析 XML 文件。您缺少文档构建器。

        //Build the document from the xmlString
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(new InputSource(new StringReader(xmlString)));
    
        //Get all the transaction elements and then loop over them
        NodeList transaction = doc.getElementsByTagName("transaction");
        for(int j = 0; j < transaction.getLength(); j++) {
            //Traverse down the transaction node till we get the billing info
            NodeList details = ((Element)transaction.item(j)).getElementsByTagName("details");
            NodeList account = ((Element)details.item(0)).getElementsByTagName("account");
            NodeList billinginfo = ((Element)account.item(0)).getElementsByTagName("billing_info");
    
            System.out.println("===Billing Info===");
            System.out.println("Type: "+((Element)billinginfo.item(0)).getAttribute("type"));
    
            //Get all children nodes from billing info
            NodeList billingChildren = billinginfo.item(0).getChildNodes();
    
            for(int i = 0; i < billingChildren.getLength(); i++) {
                Node current = billingChildren.item(i);
                //Only want stuff from ELEMENT nodes
                if(current.getNodeType() == Node.ELEMENT_NODE) {
                    System.out.println(current.getNodeName()+": "+current.getTextContent());
                }
            }
        }
    

    这会从您的示例中生成以下内容。

    ===Billing Info===
    Type: credit_card
    first_name: asdasdasd
    last_name: asdasdasd23434
    address1:
    address2:
    city:
    state:
    zip:
    country:
    phone:
    vat_number:
    card_type: Visa
    year: 2039
    month: 6
    first_six: 111111
    last_four: 9999
    

    【讨论】:

      【解决方案2】:

      您可以使用Declarative Stream Mapping (DSM) 流解析库轻松解析复杂的XML。

      您只需定义要从 XML 中提取的数据的映射

      这里是您的 XML 的映射定义。

      DSM 忽略命名空间。

      result:     
         type: array
         path: /transactions/transaction       
         fields:
             source:          
             account:
                type: array
                path: details/account
                fields:       
                   accountCode: 
                     path: account_code                 
                   firstName: 
                     path: first_name                 
                   lastName: 
                     path: last_name                 
                   first_six: 
                     path: billing_info/first_six
                     dataType: int                 
                   last_four: 
                     path: billing_info/last_four
                     dataType: int                 
                   card_type: 
                     path: billing_info/card_type
      

      解析 XML 的 Java 代码:

      DSM dsm=new DSMBuilder(new File("path/to/mapping.yaml")).setType(DSMBuilder.TYPE.XML).create();
      Object result=  dsm.toObject(xmlFileContent);
      // json represntation fo result
      dsm.getObjectMapper().writerWithDefaultPrettyPrinter().writeValue(System.out, object);
      

      这是输出:

      [ {
        "source" : "subscription",
        "account" : [ {
          "accountCode" : "234234234",
          "firstName" : "asdadad",
          "lastName" : "asdadasd3433",
          "card_type" : "Visa",
          "first_six" : 111111,
          "last_four" : 9999
        } ]
      } ]
      

      如果您想直接反序列化为 POJO 类,则可以使用 DSM

      【讨论】:

        【解决方案3】:

        如果可能,请使用 Jackson 之类的 API 来解析您的 XML。 Here 是一个对你有帮助的问题。

        【讨论】:

          【解决方案4】:

          您正在执行eElement3.getElementsByTagName("credit_year"),但您的 xml 中没有 credit_year。它只是 'year' 而不是 xml 中的 'credit_year'。所以试试eElement3.getElementsByTagName("year")

          【讨论】:

            猜你喜欢
            • 2021-07-25
            • 2015-05-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-02-03
            • 1970-01-01
            相关资源
            最近更新 更多