Java Vector Field (Private Member) Accumulator는 내 젖소를 저장하지 않습니다!

StackOverflow https://stackoverflow.com/questions/237561

  •  04-07-2019
  •  | 
  •  

문제

편집 :이 코드는 괜찮습니다. 의사 코드에 존재하지 않는 논리 버그를 찾았습니다. 나는 Java 경험이 부족하다는 것을 비난하고있었습니다.

에서 의사 코드 아래에서 보여지는 XML을 구문 분석하려고합니다. 어리석은 예일 수도 있지만 내 코드는 너무 크거나 구체적이어서 누구나 그것을보고 게시 된 답변으로부터 배우기에 실제 가치를 얻기에는 너무 많았습니다. 따라서 이것은 더 재미 있고 다른 사람들이 나뿐만 아니라 답으로부터 배울 수 있기를 바랍니다.

저는 Java를 처음 사용하지만 경험이 풍부한 C ++ 프로그래머는 제 문제가 Java 언어에 대한 이해에 있다고 믿습니다.

문제 : 파서가 마무리되면 내 벡터는 초기화되지 않은 젖소로 가득합니다. 기본 용량으로 소의 벡터를 만듭니다 (C ++ STL 벡터와 같은 경우 "크기"에 영향을 미치지 않아야합니다). 구문 분석 후 소 벡터의 내용을 인쇄하면 벡터의 올바른 크기를 제공하지만 모든 값은 설정되지 않은 것처럼 보입니다.

정보 : 벡터가없는 다른 파서와 함께이 작업을 수행했습니다. 필드 그러나이 경우 벡터를 사용하여 소 속성을 축적하고 싶습니다.

MoreInfo : 제네릭 (벡터 <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;
        }
    }
}
도움이 되었습니까?

해결책

코드는 나에게 괜찮아 보인다. 각 함수의 시작 부분에 중단 점을 설정하고 디버거에서 시청하거나 인쇄문을 추가합니다. 내 직감은 나에게도 그것을 말해줍니다 characters() 또는 또는 setColor() 그리고 setAge() 올바르게 작동하지 않지만 그것은 단지 추측 일뿐입니다.

다른 팁

소가 초기화되지 않았다고 말할 때 문자열 특성이 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 == ... 대신 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(Carom=])

"... Sax Parsers는 모든 인접한 문자 데이터를 단일 청크로 반환하거나 여러 덩어리로 나눌 수 있습니다 ..."

나는 당신이 제공 한 간단한 예에서 그 문제를 해결할 것이라고 의심하지만, 이것은 또한 더 복잡한 문제의 단순화 된 버전이라고 언급했습니다. 원래 문제에서 XML이 큰 텍스트 블록으로 구성되면 고려해야 할 사항입니다.

마지막으로, 다른 사람들이 언급했듯이, 가능하다면 XML 마샬링 라이브러리 (예 : JaxB, Castor, Jibx, Xmlbeans, Xstream)를 고려하는 것이 좋습니다.

나는이 디자인의 열렬한 팬이 아니라고 말해야합니다. 그러나 당신의 캐릭터가 호출되었다고 확신합니까? (아마도 몇 가지 시스템이 도움이 될 것입니다). 그것이 부름을받지 못하면, 당신은 초기화되지 않은 소로 끝날 것입니다.

또한 검증 문제에 대해 더 강력해야하므로 이와 같은 XML 파서를 직접 구현하려고 시도하지 않습니다.

Sax 또는 Dom4J를 사용할 수 있거나 더 나은 Apache Digester를 사용할 수 있습니다.

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top