2010-09-29 21 views
5

Tôi phải phân tích cấu trúc XML trong JAVA bằng cách sử dụng trình phân tích cú pháp SAX.Phân tích cấu trúc XML với số lượng truy cập không xác định bằng SAX

Vấn đề là cấu trúc đệ quy với số lần truy cập không xác định. Điều này vẫn không phải là một vấn đề lớn như vậy, vấn đề lớn là tôi không thể tận dụng chức năng không gian tên XML và các thẻ giống nhau trên mọi mức đệ quy.

Dưới đây là ví dụ về cấu trúc.

<?xml version="1.0" encoding="UTF-8"?> 
<RootTag> 
    <!-- LOADS OF OTHER TAGS --> 
    <Tags attribute="value"> 
     <Tag attribute="value"> 
      <SomeOtherTag></SomeOtherTag> 
      <Tags attribute="value"> 
       <Tag attribute="value"> 
        <SomeOtherTag></SomeOtherTag> 
        <Tags attribute="value"> 
         <!-- MORE OF THE SAME STRUCTURE --> 
        </Tags> 
       </Tag> 
      </Tags> 
     </Tag> 
    </Tags> 
    <!-- LOADS OF OTHER TAGS --> 
</RootTag> 

Như bạn có thể thấy có một lần đệ quy, một số lượng truy cập không xác định tốt hơn. Bây giờ vấn đề của tôi là làm thế nào để trích xuất tất cả dữ liệu cho mỗi đệ quy và lưu nó trong một ví dụ HashMap.

tôi có thể xác định một ContentHandler cho sự xuất hiện của Tags và có nó trích xuất nội dung trong một HashMap và đưa nó trở lại trong một bậc thầy HashMap định nghĩa trong xử lý nội dung chính nhưng tôi không chắc chắn nóng để làm điều này.

Làm cách nào để trích xuất và lưu nội dung của cấu trúc XML đệ quy mà không sử dụng không gian tên?

+0

Bạn cần các phím nào của HashMap? một giá trị thuộc tính? – LarsH

+0

Có các phím sẽ là giá trị thuộc tính. –

Trả lời

3

Khám phá this set of Javaworld articles on using SAX. Nó thể hiện một cách dễ dàng để phân tích một cấu trúc XML đệ quy bằng SAX. Nó tạo ra một máy trạng thái hiển thị cho mỗi phần tử mà các phần tử nó có thể chứa. Khi contentHandler của bạn duyệt qua xml, nó giữ một ngăn xếp hiển thị phần tử nào nó hiện đang ở trên.

+0

Cảm ơn rất nhiều. Điều này khá chính xác những gì tôi đang tìm kiếm. –

+0

+1 Liên kết đó đặc biệt hữu ích. –

0

Nếu bạn muốn phân tích cú pháp XML qua SAX đệ quy, bạn phải sử dụng Stack và kiểm tra độ sâu trong cấu trúc XML của bạn. Đối với cấu trúc XML của tôi ở định dạng này (độ sâu tối đa là 3):

<Response action='categories'> 
    <Categories> 
     <Category name='{name}' id='{id}' numSubcategories='{num}'> 
      <Category name='{name}' id='{id}' numSubcategories='{num}'> 
       <Category name='{name}' id='{id}' numSubcategories='0'/> 
       ... 
      </Category> 
      ... 
     </Category> 
     ... 
    </Categories> 
</Response> 

Tôi đã sử dụng mã giả Java này và nó hoạt động khá tốt trong ứng dụng Android của tôi (cho độ sâu đã biết). Nếu bạn không biết số lượng truy tìm và không biết chiều sâu, bạn chỉ có thể chỉnh sửa mã của mình và thay cho 3 đối tượng ArrayList (và 3 đối tượng Danh mục), bạn có thể sử dụng một bộ sưu tập động (ví dụ: ArrayList<ArrayList<Category>>) và đặt ArrayList<Category> vào chỉ số ArrayList<ArrayList<Category>> sử dụng chỉ mục, hiển thị phương thức getDepth().

public class CategoriesResponse extends Response 
{ 
    private Stack<String> mTagStack = new Stack<String>(); 
    private ArrayList<Category> mCategories1; 
    private ArrayList<Category> mCategories2; 
    private ArrayList<Category> mCategories3; 
    Category mCategory1; 
    Category mCategory2; 
    Category mCategory3; 
    private int mCurrentDepth = 0; 


    public ArrayList<Category> getCategories() 
    { 
     return mCategories1; 
    } 


    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException 
    { 
     super.startElement(uri, localName, qName, attributes); 

     ... 

     if(localName.equals("Category")) 
     { 
      // push element into the stack 
      mTagStack.push(localName); 

      // get data 
      int id = Integer.parseInt(attributes.getValue("id")); 
      String name = attributes.getValue("name"); 
      int numSubcategories = Integer.parseInt(attributes.getValue("numSubcategories")); 

      // create new Category 
      if(getDepth()==1) 
      { 
       mCategory1 = new Category(id, name); 
       mCategory1.setSubcategoriesSize(numSubcategories); 
       mCategory1.setSubcategories(null); 
       if(mCurrentDepth<getDepth()) mCategories1 = new ArrayList<Category>(); // deeping down so create new list 
      } 
      else if(getDepth()==2) 
      { 
       mCategory2 = new Category(id, name); 
       mCategory2.setSubcategoriesSize(numSubcategories); 
       mCategory2.setSubcategories(null); 
       if(mCurrentDepth<getDepth()) mCategories2 = new ArrayList<Category>(); // deeping down so create new list 
      } 
      else if(getDepth()==3) 
      { 
       mCategory3 = new Category(id, name); 
       mCategory3.setSubcategoriesSize(numSubcategories); 
       mCategory3.setSubcategories(null); 
       if(mCurrentDepth<getDepth()) mCategories3 = new ArrayList<Category>(); // deeping down so create new list 
      } 

      // debug output 
      if(mCurrentDepth<getDepth()) Log.d("SAX_TEST", getPath() + " | " + getDepth() + " | DEEPING DOWN"); 
      else if(mCurrentDepth>getDepth()) Log.d("SAX_TEST", getPath() + " | " + getDepth() + " | DEEPING UP"); 
      else if(mCurrentDepth==getDepth()) Log.d("SAX_TEST", getPath() + " | " + getDepth() + " | STAYING"); 

      // set current depth 
      mCurrentDepth = getDepth(); 
      return; 
     } 
    } 


    public void characters(char[] ch, int start, int length) throws SAXException 
    { 
     super.characters(ch, start, length); 
     ... 
    } 


    public void endElement(String uri, String localName, String qName) throws SAXException 
    { 
     super.endElement(uri, localName, qName); 

     ... 

     if(localName.equals("Category")) 
     { 
      // debug output 
      Log.d("SAX_TEST", "END OF THE ELEMENT IN DEPTH " + getDepth() + " | " + mCurrentDepth); 

      // deeping up so set sublist for current category 
      if(getDepth()!=mCurrentDepth) 
      { 
       if(getDepth()==2) mCategory2.setSubcategories(mCategories3); 
       if(getDepth()==1) mCategory1.setSubcategories(mCategories2); 
      } 

      // add current category to list 
      if(getDepth()==1) 
      { 
       mCategories1.add(mCategory1); 
      } 
      else if(getDepth()==2) 
      { 
       mCategories2.add(mCategory2); 
      } 
      else if(getDepth()==3) 
      { 
       mCategories3.add(mCategory3); 
      } 

      // pop element from stack 
      mTagStack.pop(); 
      return; 
     } 
    } 


    // debug output - write current path 
    private String getPath() 
    { 
     String buffer = ""; 
     Enumeration<String> e = mTagStack.elements(); 
     while (e.hasMoreElements()) 
     { 
      buffer = buffer + "/" + (String) e.nextElement(); 
     } 
     return buffer; 
    } 


    // get current depth of stack 
    private int getDepth() 
    { 
     return mTagStack.size(); 
    } 
} 
Các vấn đề liên quan