2011-07-28 61 views
0

感謝以前的回覆。如何在XML中獲取屬性

我用java(SAXParser的)解析XML文件,我不知道如何解析使用屬性值的屬性值(元數據)。我給出了兩個主要categoy <category name="XYZ" /> <category name="ABC"/> '

  <subcategory name="" loc="C://program files" link="www.sample.com" parentnode="XYZ"/> 
      <subcategory name="" loc="C://program files" link="http://" parentnode="ABC"/>` 

在子類我都掛有parentnode屬性的主要類別。我的問題是我想獲得所有僅包含特定父屬性的屬性。 (Ex)我想要所有的屬性只存在於父屬性「ABC」中。這有可能獲得價值。

+1

你怎麼辦 「分析」? DOM,SAX,XPath,還是你推出自己的? –

+0

忘了包括, – RAAAAM

+1

你有超過你需要解析XML控制使用的SAXParser?我的意思是你自己決定它看起來如何?然後我發現使用'parentnode'屬性很奇怪。 ''似乎是構建xml更好的方法。並在SAX中捕獲類名爲「blah」的事件,然後解析(或跳過)應該不會太難。 SAX教程詳細解釋瞭如何做到這一點。作爲事後的想法:也許你可以改變XSD/XML來使用節點和值,以及更少的屬性。取決於你的設計。 – Wivani

回答

4

請問下面的代碼是你的問題的解決方案?

XML

<?xml version="1.0"?> 
<categories> 
    <category name="ABC"> 
     <subcategory name="123" 
      loc="C://program files" 
      link="www.sample.com" 
      parentnode="ABC"/> 
     <subcategory name="456" 
      loc="C://program files" 
      link="http://" 
      parentnode="ABC"/> 
    </category> 

    <category name="XYZ"> 
     <subcategory name="123" 
      loc="C://program files" 
      link="www.sample.com" 
      parentnode="XYZ"/> 
     <subcategory name="456" 
      loc="C://program files" 
      link="http://abc.com" 
      parentnode="XYZ"/> 
    </category> 
</categories> 

JAVA

package com.stackoverflow; 

import java.io.File; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 

import org.w3c.dom.Document; 
import org.w3c.dom.NamedNodeMap; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 

public class Question6855476 { 
private static final String CFG_XML_PATH = "D:\\sample\\path\\question6855476.xml"; 
private static final String searchArg = "ABC"; 

public static void main(String[] args) { 

    List locList = getLocsByCategoryName(searchArg); 
    List linkList = getLinksByCategoryName(searchArg); 

    printCollection(locList,"LOC"); 
    printCollection(linkList,"LINKS"); 

} 

private static void printCollection(List locList, String string) { 
    System.out.println(); 
    System.out.println("### Collection: "+string+"\n"); 
    if(locList.isEmpty()) { 
     System.out.println("\tNo items. Collection is empty."); 
    } else { 
     for(Object obj: locList) { 
      System.out.println("\t"+obj); 
     } 
    } 

} 

private static List getLocsByCategoryName(String catName) { 
    if(null==catName||catName.length()<=0) { 
     System.out.println("ERROR: catName is null/blank"); 
     return Collections.EMPTY_LIST; 
    } else { 
     return getSubcatAttrValuesByAttrName("loc", catName); 
    } 
} 

private static List getLinksByCategoryName(String catName) { 
    if(null==catName||catName.length()<=0) { 
     System.out.println("ERROR: catName is null/blank"); 
     return Collections.EMPTY_LIST; 
    } else { 
     return getSubcatAttrValuesByAttrName("link", catName); 
    } 
} 

private static List<Object> getSubcatAttrValuesByAttrName(String attrName, String catName) { 

    List<Object> list = new ArrayList<Object>(); 

    if(null==attrName||attrName.length()<=0) { 
     System.out.println("ERROR: attrName is null/blank"); 
    } else { 
     try { 
       File file = new File(CFG_XML_PATH); 
       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
       DocumentBuilder db = dbf.newDocumentBuilder(); 
       Document doc = db.parse(file); 
       doc.getDocumentElement().normalize(); 

       NodeList catLst = doc.getElementsByTagName("category"); 

       for (int i = 0; i < catLst.getLength(); i++) { 

        Node cat = catLst.item(i); 

        NamedNodeMap catAttrMap = cat.getAttributes(); 
        Node catAttr = catAttrMap.getNamedItem("name"); 

        if(catName.equals(catAttr.getNodeValue())){ // CLUE!!! 

         NodeList subcatLst = cat.getChildNodes(); 

         for (int j = 0; j < subcatLst.getLength(); j++) { 
          Node subcat = subcatLst.item(j); 
          NamedNodeMap subcatAttrMap = subcat.getAttributes(); 

          if(subcatAttrMap!=null) { 
           Node subcatAttr = subcatAttrMap.getNamedItem(attrName); 
           list.add(subcatAttr.getNodeValue()); 
          } 
         } 
        } 
       } 
     } catch (Exception e) { // FIXME 
      e.printStackTrace(); 
     } 
    } 
    return list; 
} 

}

我基於this article

+0

令人驚歎,謝謝。你能指導我如何使用類別名稱刪除子類別。 – RAAAAM

+0

從xml文件或java對象中刪除? –

+0

從xml文件中刪除,我想根據類別屬性名稱刪除子類別。 – RAAAAM

0

一旦你解析你將XML你可以通過數據漫步找到你所需要的,但更好的方法可能是使用XPath查詢XML。

有一些輔導材料here

+0

這個答案似乎覆蓋了比SAX更多的DOM解析,不是嗎?而OP似乎只需要解析某些節點而不是整個XML。 XPATH可能是一個解決方案,但我似乎記得它加載了整個文檔,可能不符合這裏的要求。 – Wivani

3

我假設你的意思是你想獲得subcategory元素的所有屬性與parentnode屬性值等於「ABC」?所以你想在你給的例子中得到屬性(name="" loc="C://program files" link="http://" parentnode="ABC")

基本解析代碼應該是這樣的:

SAXParserFactory factory = SAXParserFactory.newInstance(); 
SAXParser parser = factory.newSAXParser(); 
MySAXHandler handler = new MySAXHandler(); 
handler.setDesireParentNodeAttributeValue("ABC"); 
parser.parse(xmlInputStream, handler); 

/* 
*this list contains all the attributes of the subcategory element that has 
* parentnode attribute equals to "ABC" 
*/ 
List<Attributes> whatIWant = handler.getDesireAttributes(); 

//do whatever you wnat with "whatIWant" 

.... 

public class MySAXHandler extends DefaultHandler2 
{ 
    private String desirePrentNodeAttributeValue; 
    private List<Attributes> desireAttributes = new ArrayList<Attributes>(); 

    public void setDesireParentNodeAttributeValue(String val) 
    { 
     this.desirePrentNodeAttributeValue = val; 
    } 

    public List<Attributes> getDesireAttributes() 
    { 
     return desireAttributes; 
    } 

    public void startElement(String uri, 
         String localName, 
         String qName, 
         Attributes attributes) 
    throws SAXException 
    { 
     if ("subcategory".equals(localName) 
      && attributes 
       .getValue("parentnode") 
       .equals(this.desirePrentNodeAttributeValue)) 
     { 
      desireAttributes.add(attributes); 
     } 
    } 
} 
+0

+1使用SAX – Wivani