2011-07-28 62 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