2010-10-11 105 views
1
<inputs> 
    <MAT_NO>123</MAT_NO> 
    <MAT_NO>323</MAT_NO> 
    <MAT_NO>4223</MAT_NO> 
    <FOO_BAR>122</FOO_BAR> 
    <FOO_BAR>125</FOO_BAR> 
</inputs> 

我必須解析上面的XML。解析後,我希望這些值是在Map<String, List<String>>對應於子節點的鍵值 - MAT_NO,foo_bar這樣 價值觀和 - 孩子的價值觀節點-123,323等解析XML並轉換爲集合

以下是我的投籃。有沒有更好的方式做到這一點?

public class UserInputsXmlParser extends DefaultHandler { 

private final SaveSubscriptionValues subscriptionValues = null; 
private String nodeValue = ""; 
private final String inputKey = ""; 
private final List<String> valuesList = null; 
private Map<String, List<String>> userInputs; 

public Map<String, List<String>> parse(final String strXML) { 
    try { 
    final SAXParserFactory parserFactory = SAXParserFactory 
    .newInstance(); 
    final SAXParser saxParser = parserFactory.newSAXParser(); 
    saxParser.parse(new InputSource(new StringReader(strXML)), this); 
    return userInputs; 
    } catch (final SAXException e) { 
    e.printStackTrace(); 
    throw new MyException("", e); 
    } catch (final IOException e) { 
    e.printStackTrace(); 
    throw new MyException("", e); 
    } catch (final ParserConfigurationException e) { 
    e.printStackTrace(); 
    throw new MyException("", e); 
    } catch (final Exception e) { 
    e.printStackTrace(); 
    throw new MyException("", e); 
    } 
} 

@Override 
public void startElement(final String uri, final String localName, 
    final String qName, final Attributes attributes) 
    throws SAXException { 
    nodeValue = ""; 

    if ("inputs".equalsIgnoreCase(qName)) { 
    userInputs = MyUtil.getNewHashMap(); 
    return; 
    } 

} 

@Override 
public void characters(final char[] ch, final int start, final int length) 
    throws SAXException { 
    if (!MyUtil.isEmpty(nodeValue)) { 
    nodeValue += new String(ch, start, length); 
    } else { 
    nodeValue = new String(ch, start, length); 
    } 
} 

@Override 
public void endElement(final String uri, final String localName, 
    final String qName) throws SAXException { 
    if (!"inputs".equalsIgnoreCase(qName)) { 
    storeUserInputs(qName, nodeValue); 
    } 

} 

/** 
    * @param qName 
    * @param nodeValue2 
    */ 
private void storeUserInputs(final String qName, final String nodeValue2) { 
    if (nodeValue2 == null || nodeValue2.trim().equals("")) { return; } 
    final String trimmedValue = nodeValue2.trim(); 
    final List<String> values = userInputs.get(qName); 
    if (values != null) { 
    values.add(trimmedValue); 
    } else { 
    final List<String> valueList = new ArrayList<String>(); 
    valueList.add(trimmedValue); 
    userInputs.put(qName, valueList); 
    } 
} 

public static void main(final String[] args) { 
    final String sample = "<inputs>" + "<MAT_NO>154400-0000</MAT_NO>" 
    + "<MAT_NO> </MAT_NO>" + "<MAT_NO>154400-0002</MAT_NO>" 
    + "<PAT_NO>123</PAT_NO><PAT_NO>1111</PAT_NO></inputs>"; 
    System.out.println(new UserInputsXmlParser().parse(sample)); 
} 

} 

UPDATE:<inputs>節點的孩子是動態的。我會知道只有根節點。

回答

0

對於這個基本的東西,看看xpath。

+0

嗨史蒂文,對不起,我剛剛更新了這個問題。輸入的子節點是動態的 – HanuAthena 2010-10-11 07:45:27

1

您是否必須提供解決方案作爲SAX事件處理程序的一部分?如果沒有,那麼你可以使用周圍的許多XML庫之一,如dom4j。讓解決方案簡單得多;

public static void main(String[] args) throws Exception 
{ 
    String sample = "<inputs>" + "<MAT_NO>154400-0000</MAT_NO>" 
    + "<MAT_NO> </MAT_NO>" + "<MAT_NO>154400-0002</MAT_NO>" 
    + "<PAT_NO>123</PAT_NO><PAT_NO>1111</PAT_NO></inputs>"; 

    System.out.println(parse(sample)); 
} 

static Map<String,List<String>> parse(String xml) throws Exception 
{ 
    Map<String,List<String>> map = new HashMap<String,List<String>>(); 

    SAXReader reader = new SAXReader(); 
    Document doc = reader.read(new StringReader(xml)); 

    for (Iterator i = doc.getRootElement().elements().iterator(); i.hasNext();) 
    { 
     Element element = (Element)i.next(); 

     //Maybe handle elements with only whitespace text content 

     List<String> list = map.get(element.getName()); 
     if (list == null) 
     { 
      list = new ArrayList<String>(); 
      map.put(element.getName(), list); 
     } 
     list.add(element.getText()); 
    } 

    return map; 
}