2015-01-24 3 views
0

에 의해 검색이 문자열 가입 : 나는 mkyong의 튜토리얼 here의 예제를 시도나는이 같은 XML 파일이 SAX

<?xml version="1.0" encoding="UTF-8"?> 
<Article> 
    <ArticleTitle>Java-SAX Tutorial</ArticleTitle> 
    <Author> 
     <FamilyName>Yong</FamilyName> 
     <GivenName>Mook</GivenName> 
     <GivenName>Kim</GivenName> 
     <nickname>mkyong</nickname> 
     <salary>100000</salary> 
    </Author> 
    <Author> 
     <FamilyName>Low</FamilyName> 
     <GivenName>Yin</GivenName> 
     <GivenName>Fong</GivenName> 
     <nickname>fong fong</nickname> 
     <salary>200000</salary> 
    </Author> 
</Article> 

을하고 나는 그것이 SAX를 사용하는 완벽하게 데이터를 검색 할 수 있습니다, 그것은 나를 제공 :

Article Title : Java-SAX Tutorial 
Given Name : Kim 
Given Name : Mook 
Family Name : Yong 
Given Name : Yin 
Given Name : Fong 
Family Name : Low 

하지만 그것은 나에게 같은 것을주고 싶어 : 다른 측면에서

Article Title : Java-SAX Tutorial 
Author : Kim Mook Yong 
Author : Yin Fong Low 

을, 노드 Author의 일부 자식 노드를 검색하고 싶습니다. 모든 노드 변수를 문자열 변수에 넣고 표시합니다.

은 내가 할 시도 수정과 저자 분석하기 위해 사용하는 클래스입니다 :

public class ReadAuthors { 

    public void parse(String filePath) { 

     try { 

      SAXParserFactory factory = SAXParserFactory.newInstance(); 
      SAXParser saxParser = factory.newSAXParser(); 

      DefaultHandler handler = new DefaultHandler() { 

       boolean bFamilyName = false; 
       boolean bGivenName = false; 

       @Override 
       public void startElement(String uri, String localName,String qName, 
          Attributes attributes) throws SAXException { 

        if (qName.equalsIgnoreCase("FamilyName")) { 
         bFamilyName = true; 
        } 

        if (qName.equalsIgnoreCase("GivenName")) { 
         bGivenName = true; 
        } 

      } 

      @Override 
      public void endElement(String uri, String localName, 
       String qName) throws SAXException { 

      } 

      @Override 
      public void characters(char ch[], int start, int length) throws SAXException { 

       String fullName = ""; 

       String familyName = ""; 
       String givenName =""; 

       if (bFamilyName) { 
        familyName = new String(ch, start, length); 
        fullName += familyName; 
        bFamilyName = false; 
       } 

       if (bGivenName) { 
        givenName = new String(ch, start, length); 
        fullName += " " + givenName; 
        bGivenName = false; 
       } 

       System.out.println("Full Name : " + fullName); 

      } 
      }; 

      saxParser.parse(filePath, handler); 

     } catch (Exception e) { 
       e.printStackTrace(); 
     } 
    } 

} 

이 수정로를 만 나에게 ArticleTitle 가치를 제공하며 아무 것도 반환하지 않습니다 저자의 전체 이름에 관해서.

ArticleTitle 노드를 구문 분석하기위한 또 다른 클래스가 있으며 둘 다 Main 클래스에서 호출됩니다.

내가 뭘 잘못 했니? 어떻게 해결할 수 있습니까?

+1

JAXB를 살펴보면 파일을 Java 객체로 쉽게 파싱 할 수있다. [이 다른 질문] (http://stackoverflow.com/q/14986221/2071828)을보십시오. –

+0

@BoristheSpider SAX보다 빠릅니다. 구문 분석 할 XML 파일이 상당히 많기 때문에 (처음에는 65000 이상이 될 것이고 더 길어질 것입니다) – user1885868

+1

JAXB는 SAX (또는 StAX)를 사용하므로 확실하게 훨씬 느려서는 안됩니다. 기본적으로 XML을 Java 클래스에 매핑합니다. 또한 유효성 검사를 추가하여 사용하기 편리합니다. –

답변

1

fullName 변수는 characters 메서드가 호출 될 때마다 덮어 씁니다. 그 변수를 핸들러로 옮겨야한다고 생각합니다. 작성자가 시작될 때 빈 문자열이있는 init과 끝나면 작성합니다. 연결은 당신이했던 것처럼 작동해야합니다. 나는 이것을 시도하지 않았지만 similear가 작동해야한다 :

public class ReadAuthors { 

    public void parse(String filePath) { 

     try { 

      SAXParserFactory factory = SAXParserFactory.newInstance(); 
      SAXParser saxParser = factory.newSAXParser(); 

      DefaultHandler handler = new DefaultHandler() { 

       boolean bName = false; 
       String fullName = ""; 

       @Override 
       public void startElement(String uri, String localName,String qName, 
          Attributes attributes) throws SAXException { 

        if (qName.equalsIgnoreCase("FamilyName")) { 
         bName = true; 
        } 

        if (qName.equalsIgnoreCase("GivenName")) { 
         bName = true; 
        } 

        if (qName.equalsIgnoreCase("Author")) { 
         fullName = ""; 
        } 

      } 

      @Override 
      public void endElement(String uri, String localName, 
       String qName) throws SAXException { 
        if (qName.equalsIgnoreCase("Author")) { 
         System.out.println("Full Name : " + fullName); 
        } 
      } 

      @Override 
      public void characters(char ch[], int start, int length) throws SAXException { 

       String name = ""; 

       if (bName) { 
        name = new String(ch, start, length); 
        fullName += name; 
        bName = false; 
       } 

      } 
      }; 

      saxParser.parse(filePath, handler); 

     } catch (Exception e) { 
       e.printStackTrace(); 
     } 
    } 

}