2008-10-26 19 views
1

편집 :이 코드는 문제가 없습니다. 내 의사 코드에 존재하지 않는 어딘가에 로직 버그를 발견했습니다. 나는 자바 경험 부족으로 그것을 비난했다.자바 벡터 필드 (전용 멤버) 축약 기가 나의 암소를 저장하지 않습니다!

아래의의사 코드에서 나는 XML을 구문 분석하려고합니다. 어리석은보기일지도 모르지만 내 코드가 너무 커서 특정 사람이 그것을보고 실제 답변을 통해 실제 가치를 얻지 못했습니다. 그래서 이것은 더 재미 있고, 다른 사람들도 저뿐만 아니라 대답에서 배울 수 있기를 바랍니다.

저는 Java를 처음 접했지만 경험이 풍부한 C++ 프로그래머입니다. 제 문제는 Java 언어에 대한 이해에 있습니다.

문제점 : 파서가 완료되면 내 벡터에 초기화되지 않은 Cow가 가득합니다. 나는 C++ STL Vector와 같은 기본 용량을 가진 Cows를 만듭니다. 구문 분석 후에 Cow Vector의 내용을 출력하면 Vector의 크기가 적절하지만 모든 값이 설정되지 않은 것처럼 보입니다.

Info : Vector가없는 다른 파서로이 작업을 성공적으로 마쳤습니다. 필드이 경우 Vector를 사용하여 Cow 속성을 축적하고 싶습니다.

MoreInfo : generics (Vector < Cow>)를 사용할 수 없으므로 여기 저를 가리 키지 마십시오. :)

미리 감사드립니다.

<pluralcow> 
     <cow> 
      <color>black</color> 
      <age>1</age> 
     </cow> 
     <cow> 
      <color>brown</color> 
      <age>2</age> 
     </cow> 
     <cow> 
      <color>blue</color> 
      <age>3</age> 
     </cow> 
</pluralcow> 

public class Handler extends DefaultHandler{ 
    // vector to store all the cow knowledge 
    private Vector m_CowVec; 

    // temp variable to store cow knowledge until 
    // we're ready to add it to the vector 
    private Cow  m_WorkingCow; 

    // flags to indicate when to look at char data 
    private boolean m_bColor; 
    private boolean m_bAge; 

    public void startElement(...tag...) 
    { 
     if(tag == pluralcow){ // rule: there is only 1 pluralcow tag in the doc 
       // I happen to magically know how many cows there are here.    
       m_CowVec = new Vector(numcows); 
     }else if(tag == cow){ // rule: multiple cow tags exist 
      m_WorkingCow = new Cow(); 
     }else if(tag == color){ // rule: single color within cow 
      m_bColor = true; 
     }else if(tag == age){ // rule: single age within cow 
      m_bAge = true; 
     } 
    } 

    public void characters(...chars...) 
    { 
     if(m_bColor){ 
      m_WorkingCow.setColor(chars); 
     }else if(m_bAge){ 
      m_WorkingCow.setAge(chars); 
     } 
    } 

    public void endElement(...tag...) 
    { 
     if(tag == pluralcow){ 
      // that's all the cows 
     }else if(tag == cow){ 
      m_CowVec.addElement(m_WorkingCow);  
     }else if(tag == color){ 
      m_bColor = false; 
     }else if(tag == age){ 
      m_bAge = false; 
     } 
    } 
} 

답변

1

코드는 나에게 잘 들립니다. 각 중단 점을 각 함수의 시작 부분에 설정하고 디버거에서 보거나 몇 개의 print 문을 추가합니다. 내 직감은 characters()이 호출되지 않았거나 setColor()setAge()이 올바르게 작동하지 않는다고 알려주지 만 그저 추측입니다.

0

나는이 디자인을 좋아하지 않는다. 그러나 캐릭터가 불려지는 것이 확실합니까? (아마도 몇 가지 system.outs 도움이 될). 절대 호출하지 않으면 초기화되지 않은 소로 끝날 것입니다.

또한 필자는 검증 문제에 대해보다 견고해야하므로 XML 파서를 직접 구현하려고하지는 않습니다.

SAX 또는 DOM4J를 사용하거나 더 나은 방법으로 Apache digester를 사용할 수 있습니다.

+0

Java에서 SAX 파서에 대한 참조가 있습니까? 나는 작고 빠른 것이 최우선 과제이므로 블랙 베리를 위해 글을 쓰고있다. –

+0

또한 이것은 org.xml.sax.helpers.DefaultHandler의 오버 라이드입니다. –

+0

표준 파서와 비슷하지만 실제 클래스인지 또는 C++ SAX 파서의 개별 번역인지 확실하지 않습니다. .. 여전히 유효성이 확인되지 않으면 지저분한 XML을 처리 할 수있는 무언가가 필요하다고 생각합니다. 아파치 소화기를보고 ... – Uri

0

또한 스키마가있는 경우 JaxB 또는 다른 코드 생성기를 사용하여 XML 인터페이스 코드의 개발 속도를 높입니다. 코드 생성기는 SAX 또는 DOM4J로 직접 작업하는 많은 복잡한 작업을 숨 깁니다.

3

Cow가 초기화되지 않았다면 String 속성을 null로 초기화합니까? 아니면 빈 문자열?

나는이 의사 코드는 것을 당신이 언급 알아,하지만 난 그냥 몇 가지 잠재적 인 문제를 지적하고 싶었 : 대신 태그의 (...)

public void startElement(...tag...) 
    { 
     if(tag == pluralcow){ // rule: there is only 1 pluralcow tag in the doc 
       // I happen to magically know how many cows there are here.      
       m_CowVec = new Vector(numcows); 
     }else if(tag == cow){ // rule: multiple cow tags exist 
       m_WorkingCow = new Cow(); 
     }else if(tag == color){ // rule: single color within cow 
       m_bColor = true; 
     }else if(tag == age){ // rule: single age within cow 
       m_bAge = true; 
     } 
    } 

당신 정말 사용해야 tag.equals을 == ... 여기.

public void characters(...chars...) 
{ 
    if(m_bColor){ 
      m_WorkingCow.setColor(chars); 
    }else if(m_bAge){ 
      m_WorkingCow.setAge(chars); 
    } 
} 

나는이 사실을 알고 있다고 가정하지만이 방법은 실제로 시작 및 끝 인덱스가있는 문자 버퍼로 호출됩니다. 이 http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#characters(char[],%20int,%20int)

"... SAX 파서는 연속하는 모든 를 반환 할 수 있습니다 문자 (...)가 각각의 호출에 작은 덩어리를 반환, 하나의 텍스트 블록에 대해 여러 번 호출 할 수도

참고 하나의 덩어리, 또는 에서 문자 데이터 그들은 내가 당신이 제공하는 간단한 예에서 그 문제로 실행하겠습니다 의심 "... 여러 덩어리로

을 분할 해,하지만 당신은 또한 이것이 인 언급 보다 복잡한 p의 단순화 된 버전 흠집. 원래 문제가 XML에 큰 텍스트 블록으로 구성되어 있다면 고려해야 할 사항입니다.

마지막으로 다른 사람들이 언급했듯이 가능한 경우 XML 마샬링 라이브러리 (예 : JAXB, Castor, JIBX, XMLBeans, XStream)를 고려하는 것이 좋습니다.

+0

그레이트 대답! 1) 문자 버퍼 : 예, 의사 코드에서 단순화했습니다. 2) String.equals() : 예, 단순화. 3) 여러 번 호출 된 문자() : awesome note! 나는 그 사건을 확실히 처리해야 할 것이다. 4) Blackberry JDE 4 (J2ME)에서 작동하는 마샬링 라이브러리를 아직 찾지 못했습니다. –

+0

아, 나는 당신이 J2ME 프로그래밍을하고 있다는 것을 몰랐다. 이는 조금 다른 점입니다. 추가 추상화 레이어와 함께 제공되는 처리 오버 헤드를 피하는 것이 좋습니다. –