Java Vector Field (Private Member) Accumulator는 내 젖소를 저장하지 않습니다!
문제
편집 :이 코드는 괜찮습니다. 의사 코드에 존재하지 않는 논리 버그를 찾았습니다. 나는 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와 직접 작업하는 복잡성을 많이 숨 깁니다.