2010-03-30 5 views
2

에 파괴되고 해당하지 '&', 하나 내 내 XML 요소는 신비 반

임은 실제 XML을 구문 분석 않는 SAXParser를 객체를 사용.

이 작업은 일반적으로 URL을 XMLReader.Parse 메서드에 전달하여 수행됩니다. XML이 웹 서비스에 대한 POST 요청에서오고 있기 때문에 그 결과를 String으로 저장하고 StringReader/InputSource를 사용하여이 문자열을 XMLReader.Parse 메서드에 다시 공급합니다.

그러나 XMLstring의 2001 번째 문자에서 이상한 일이 일어나고 있습니다.
문서 처리기의 '문자'메서드는 startElement와 endElement 메서드 사이에서 TWICE로 호출되므로 효과적으로 내 문자열 (이 경우 프로젝트 제목)을 두 조각으로 나눕니다. 내 문자 방식으로 객체를 인스턴스화하기 때문에 하나 대신 두 개의 객체가 생성됩니다.

이 줄 "낮은"와 "레벨"사이에 파괴 문자열 화재 '문자'두 번에 약 2000 문자,

<title>SUMC-BOOKSTORE, LOWER LEVEL RENOVATIONS</title> 

나는 StringReader를/InputSource의 해결 방법을 무시하고 플랫 XML 파일을 공급하는 경우 XMLReader.Parse하려면, 그것은 절대적으로 잘 작동합니다.

StringReader 및/또는 InputSource에 관한 문제로 인해이 문제가 발생합니다.

다음은 XML 문자열과 구문 분석에 사용되는 메서드이며 SAXParser를 사용합니다.

public void parseXML(String XMLstring) { 
    try { 
     SAXParserFactory spf = SAXParserFactory.newInstance(); 
     SAXParser sp = spf.newSAXParser(); 
     XMLReader xr = sp.getXMLReader(); 
     xr.setContentHandler(this); 

     // Something is happening in the StringReader or InputSource 
     // That cuts the XML element in half at the 2001 character mark. 

     StringReader sr = new StringReader(XMLstring); 
     InputSource is = new InputSource(sr); 
     xr.parse(is); 


    } catch (IOException e) { 
     Log.e("CMS1", e.toString()); 
    } catch (SAXException e) { 
     Log.e("CMS2", e.toString()); 
    } catch (ParserConfigurationException e) { 
     Log.e("CMS3", e.toString()); 
    } 
} 

XML 문자열에서이 시점에 이르면 '문자'가 두 번 나오지 않는 방법에 대한 아이디어를 매우 높이 평가합니다.

또는 POST 요청을 사용하는 방법을 보여주고 URL을 구문 분석 함수에 전달하십시오.

감사합니다.

답변

5

donroby는 파서가 startElement와 endElement 사이에서 characters 메소드를 두 번 이상 호출하는 것이 가장 합당하다고 말했습니다. 그러나 그것은 "오작동"이 아니며, 일이 일어나지 않도록 사물을 봉쇄하려고해서는 안됩니다.파서는 2000 자의 버퍼를 사용하고있는 것처럼 보이지만 텍스트 노드를 여러 부분으로 나눌 수있는 다른 이유가 있습니다.

당신이해야 할 일은 문자 메소드에 데이터를 축적하고 노드의 문자 데이터를 모두 축적했다고 확신 할 때 endElement 메소드에서 나중에 처리하는 것입니다.

+0

+1. 예, 일반적인 처리 방법은 startElement 메소드에서 일종의 누산기를 작성하거나 첨부 한 다음 문자 메소드로 축적 한 다음 endElement 메소드에서 사용하고 폐기하거나 분리하는 것입니다. –

2

SAXParser에서 startElement와 endElement 사이에서 문자 메소드가 여러 번 시작되는 것은 합법입니다. 구현이 처리하고 있지 않는 경우는, 사용되는 ContentHandler가, 잘못 encode 된 문자 메소드를 가질 가능성이 높습니다.

코드 스 니펫에서 오작동 문자 메서드는 ContentHandler로 'this'를 전달할 때 코드의 다른 위치에 있다고 생각합니다. 그 코드를 게시하십시오. 그러면 해결할 수 있습니다.

는 하나의 덩어리 연속하는 문자 데이터를 반환 할 수 있습니다 문구를

SAX 파서에 주목, the Javadoc 참조하거나이 자바 독은의 ContentHandler위한 여러 덩어리

으로 분할 할 수 있습니다. ContentHandler를 사용하는 DocumentHandler를 사용하고있는 것으로 보입니다. 그러나 DocumentHandler의 javadoc에는 동일한 언어가 포함되어 있습니다.

+0

감사합니다. StringReader 및 InputSource 개체를 사용할 때 코드의 결과가 좋지 않음을 고려할 때 문제가있는 것처럼 보입니다. 이 구현을 우회하면 제작 과정에서 문제가 발생하지 않지만 올바르게 처리됩니다. XML 데이터에 사용 된 정렬 순서에 관계없이 문제는 2001 문자가 XML로 발생한다는 점을 고려하십시오. 감사! – FauxReal

+0

잘못 구현하면 때때로 오류가 발생하더라도 작동합니다. 문제는 때때로 작동하는 것처럼 보이지만 관계없이 코드에 있습니다. –

1

답장을 보내 주셔서 감사합니다. 당신의 도움으로 나는 그 문제를 해결할 수있었습니다.

온라인 자습서에서 배운 "문자"방법으로 실제 처리를하고있었습니다.

endElement 메서드로 처리를 이동하면 '문자'가 몇 번 발생했는지에 관계없이 문자를 문자열로 간단하게 연결할 수있었습니다.

나는이 작업을 Tags 사이에 부울 값을 설정하고 startElement 중에 true로 설정하고 endElement 끝에서 false로 설정함으로써이 작업을 수행했습니다.

내부 문자는, 내가

if (betweenTags) accumulation += chars; 

이 축적 문자열이 ""의 startElement의 끝에서 설정 추가했습니다.

훌륭한 작품, 깨진 요소가 없습니다.

고맙습니다!

+0

당신을 환영합니다! 이제 답변을 수락하면 누군가의 평판과 수락 비율이 향상됩니다. –

+0

오! 괜찮 감사! – FauxReal

0

나는 동일한 문제가있었습니다. 나는 이것에 구문 분석 부호를 바꾸고 작동했다 ... !!! !!!

@Override 
    public void startElement(String arg0, String arg1, String arg2, 
      Attributes arg3) throws SAXException { 
     // TODO Auto-generated method stub 
     currentstring = new String(); 
     if (arg1.equalsIgnoreCase("Order")) { 
      currentItem = new HashMap<String, String>(); 
     } 

    } 


@Override 
    public void characters(char[] arg0, int arg1, int arg2) 
      throws SAXException { 
     currentstring = currentstring + new String(arg0, arg1, arg2); 
     Log.i("Current String", currentstring); 
    } 

@Override 
    public void endElement(String arg0, String arg1, String arg2) 
      throws SAXException { 
     // TODO Auto-generated method stub 
     if (currentItem != null) { 
      currentItem.put(arg1, currentstring); 
      currentstring = ""; 
     } 

아이디어는 startElement()에서 String을 초기화하고, character()에서 append하고 endElement()에서 끝내는 것입니다.