GAE에서 완벽하게 유효한 XML을 구문 분석 할 때 "내용이 프롤로그에 허용되지 않습니다"


109

나는 지난 48 시간 동안이 절대적으로 분노한 벌레에 대해 머리를 치고 있었기 때문에 마침내 타월을 던져 여기에서 물어 보겠다고 생각했다.

AWS SimpleDB에 대한 호출에서 응답 XML을 구문 분석하려고합니다. 응답은 정상적으로 돌아오고 있습니다. 예를 들어 다음과 같을 수 있습니다.

<?xml version="1.0" encoding="utf-8"?> 
<ListDomainsResponse xmlns="http://sdb.amazonaws.com/doc/2009-04-15/">
    <ListDomainsResult>
        <DomainName>Audio</DomainName>
        <DomainName>Course</DomainName>
        <DomainName>DocumentContents</DomainName>
        <DomainName>LectureSet</DomainName>
        <DomainName>MetaData</DomainName>
        <DomainName>Professors</DomainName>
        <DomainName>Tag</DomainName>
    </ListDomainsResult>
    <ResponseMetadata>
        <RequestId>42330b4a-e134-6aec-e62a-5869ac2b4575</RequestId>
        <BoxUsage>0.0000071759</BoxUsage>
    </ResponseMetadata>
</ListDomainsResponse>

이 XML을 파서에 전달합니다.

XMLEventReader eventReader = xmlInputFactory.createXMLEventReader(response.getContent());

eventReader.nextEvent();원하는 데이터를 얻기 위해 여러 번 전화를 겁니다 .

여기에 기괴한 부분이 있습니다. 로컬 서버에서 잘 작동합니다. 응답이 들어오고 파싱하면 모두가 행복합니다. 문제는 Google App Engine에 코드를 배포 할 때 나가는 요청이 계속 작동하고 응답 XML이 100 % 동일하고 정확 해 보이지만 응답이 다음 예외와 함께 구문 분석에 실패한다는 것입니다.

com.amazonaws.http.HttpClient handleResponse: Unable to unmarshall response (ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.): <?xml version="1.0" encoding="utf-8"?> 
<ListDomainsResponse xmlns="http://sdb.amazonaws.com/doc/2009-04-15/"><ListDomainsResult><DomainName>Audio</DomainName><DomainName>Course</DomainName><DomainName>DocumentContents</DomainName><DomainName>LectureSet</DomainName><DomainName>MetaData</DomainName><DomainName>Professors</DomainName><DomainName>Tag</DomainName></ListDomainsResult><ResponseMetadata><RequestId>42330b4a-e134-6aec-e62a-5869ac2b4575</RequestId><BoxUsage>0.0000071759</BoxUsage></ResponseMetadata></ListDomainsResponse>
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.
    at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(Unknown Source)
    at com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(Unknown Source)
    at com.amazonaws.transform.StaxUnmarshallerContext.nextEvent(StaxUnmarshallerContext.java:153)
    ... (rest of lines omitted)

이 XML을 '보이지 않는 문자'또는 UTF8이 아닌 인코딩 된 문자 등에 대해 이중, 삼중, 사중으로 확인했습니다. 바이트 순서 표시 또는 그 성격의 배열에서 바이트 단위로 살펴 보았습니다. 아무것도; 내가 던질 수있는 모든 검증 테스트를 통과합니다. 더 이상하게도 Saxon 기반 파서를 사용하면 발생하지만 GAE에서만 항상 로컬 환경에서 잘 작동합니다.

완벽하게 작동하는 환경에서만 디버거를 실행할 수있을 때 문제에 대한 코드를 추적하기가 매우 어렵습니다 (GAE에서 원격으로 디버깅하는 좋은 방법을 찾지 못했습니다). 그럼에도 불구하고 기본 수단을 사용하여 다음을 포함하여 백만 가지 접근 방식을 시도했습니다.

  • 프롤로그가 있거나없는 XML
  • 줄 바꿈 포함 및 제외
  • 프롤로그에 "encoding ="속성이 있거나없는 경우
  • 두 개행 스타일
  • HTTP 스트림에 청킹 정보가있는 경우와없는 경우

그리고 나는 그것들이 상호 작용하는 것이 합리적 인 여러 조합으로 이들 대부분을 시도했습니다. 나는 내 지혜의 끝에있다. 누구든지 이전에 이와 같은 문제를 본 적이 있습니까?

감사!


아마도 더 많은 코드를 볼 필요가있을 것입니다. 또 다른 가능성은 GAE에있는 동안 로컬에서 청크되지 않는다는 것입니다. 파서에 전달하기 전에 코드를 어떻게 처리하고 있습니까?
로맹 히포

청킹 가능성도 고려했지만 파서가 던지는 오류 메시지에 전체 XML이 포함되어 있기 때문에 그렇지 않은 것 같습니다 (위에 붙여 넣기). 전체 수정 된 SDK 코드는 github.com/AdrianP/aws-sdk-for-java 에서 찾을 수 있지만 (가장 최근 커밋 확인) 거기에는 많은 코드가 있습니다. 비록 어렵 겠지만, 나는 곧 더 작은 재현 가능한 샘플을 만들려고 노력할 것입니다. 매우 복잡한 소프트웨어입니다. 피드백 주셔서 감사합니다! :)
Adrian Petrescu 2010-06-13


@Raedwald, 나는 내 질문은 전년 동기 하나 :) 이상 게시 된 이후 중복이라고 내 질문에 생각하지 않습니다
아드리안 페트 레스 쿠

1
이것은 어떻게 질문을해야하는지에 대한 예가되어야합니다. 그것을 읽어 보면 개발자로서 디버그하는 방법에 대한 다양한 통찰력을 얻었습니다 (OP 감사합니다)
Sudip Bhandari

답변:


129

XML과 XSD (또는 DTD)의 인코딩이 다릅니다.
XML 파일 헤더 : <?xml version='1.0' encoding='utf-8'?>
XSD 파일 헤더 :<?xml version='1.0' encoding='utf-16'?>

이를 유발하는 또 다른 가능한 시나리오는 XML 문서 유형 선언 이전에 무언가가 오는 경우입니다. 즉, 버퍼에 다음과 같은 내용이있을 수 있습니다.

helloworld<?xml version="1.0" encoding="utf-8"?>  

또는 공백이나 특수 문자까지.

버퍼에있을 수있는 바이트 순서 마커라는 특수 문자가 있습니다. 파서에 버퍼를 전달하기 전에 다음을 수행하십시오.

String xml = "<?xml ...";
xml = xml.trim().replaceFirst("^([\\W]+)<","<");

안녕하세요 Romain, 응답 해 주셔서 감사합니다! 프롤로그 (숨겨진 문자 포함) 이전에 버퍼에있는 내용을 여러 번 두 번 및 세 번 확인했지만 다른 항목은 없습니다. 하지만 utf-16 인코딩으로 전환 해 보겠습니다. 궁금해서 XSD가 UTF-16을 사용한다는 정보를 어디서 얻었습니까?
Adrian Petrescu

@Adrian Petrescu 죄송합니다. 이것은 단지 예일뿐입니다. DTD 또는 XSD를 사용하는 경우 XML과 일치하는지 확인하십시오. XML을 구문 분석하기 전에 문자열로 캡처하고 '|'로 묶습니다. 콘솔에 인쇄합니다. 추가 문자를 전달하고 있는지 알려줍니다.
로맹 히포

아, 알겠습니다 :) 불행히도 시도했지만이 상황에서는 그렇지 않은 것 같습니다. 어쨌든 감사합니다!
아드리안 페트 레스 쿠

1
감사! 이것은 저도 구했습니다. xml.trim (). replaceFirst ( "^ ([\\ W] +) <", "<");
stackoverflow

2
누군가 이것을 받아 들인 대답으로 만드십시오. 내 문제를 즉시 해결했습니다. "Message : <? xml version ...."으로 시작하는 메시지를 구문 분석하고있었습니다. 문제는 xml 비트 이전의 텍스트였습니다. 감사합니다 :)
Ric Jafe 2013

8

이 오류 메시지는 항상 시작 요소의 잘못된 XML 콘텐츠로 인해 발생합니다. 예 : 아주 작은 점 "." XML 요소의 시작 부분에 있습니다.

" <?xml…." 앞의 모든 문자 는 " org.xml.sax.SAXParseException : 프롤로그에 내용이 허용되지 않음 "오류 메시지를 유발 합니다.

작은 점“ . ”앞에“<?xml….

이 문제를 해결하려면 “<?xml“.

참고 : http://www.mkyong.com/java/sax-error-content-is-not-allowed-in-prolog/


3
당신이 언급 된 곳 당신은 언급해야한다 mkyong.com/java/sax-error-content-is-not-allowed-in-prolog
arulraj.net

5

나는 같은 문제에 직면했다. 제 경우에는 XML 파일이 c # 프로그램에서 생성되고 추가 처리를 위해 AS400에 공급되었습니다. 일부 분석 후 XML 파일을 생성하는 동안 UTF8 인코딩을 사용하고있는 반면 javac (in AS400)는 "UTF8 without BOM"을 사용한다는 것을 확인했습니다. 따라서 아래에 언급 된 것과 유사한 추가 코드를 작성해야했습니다.

//create encoding with no BOM
Encoding outputEnc = new UTF8Encoding(false); 
//open file with encoding
TextWriter file = new StreamWriter(filePath, false, outputEnc);           

file.Write(doc.InnerXml);
file.Flush();
file.Close(); // save and close it

5

메모장 ++에서 xml 파일을 검사하고 파일을 저장하는 동안 문제가 있었지만 상단 utf-8 xml 태그가 <?xml version="1.0" encoding="utf-8"?>

Encoding (Tab)> Encode in UTF-8 : selected (이전 Encode in UTF-8-BOM)를 사용하여 notpad ++에 파일을 저장하여 수정했습니다.


3

xml 선언을 제거하면 해결되었습니다.

<?xml version='1.0' encoding='utf-8'?>

2

내 xml 파일에서 헤더는 다음과 같습니다.

<?xml version="1.0" encoding="utf-16"? />

테스트 파일에서 파일 바이트를 읽고 데이터를 UTF-8로 디코딩 (이 파일의 헤더가 utf-16이라는 사실을 인식하지 못함)하여 문자열을 생성했습니다.

byte[] data = Files.readAllBytes(Paths.get(path));
String dataString = new String(data, "UTF-8");

이 문자열을 객체로 역 직렬화하려고 할 때 동일한 오류가 표시되었습니다.

javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Content is not allowed in prolog.

두 번째 줄을

String dataString = new String(data, "UTF-16");

나는 개체를 정상적으로 역 직렬화 할 수 있었다. 따라서 Romain이 위에서 언급했듯이 인코딩이 일치해야합니다.


1

내 xml 파일에서 "내용이 프롤로그에서 허용되지 않습니다"라는 동일한 문제에 직면했습니다.

해결책

처음에 내 루트 폴더는 '# Filename '이었습니다.

첫 번째 문자 '#'을 제거하면 오류가 해결되었습니다.

#filename을 제거 할 필요가 없습니다 ...이 방법으로 시도하십시오 ..

Unmarshaller 메서드에 File 또는 URL 개체를 전달하는 대신 FileInputStream을 사용하십시오.

File myFile = new File("........");
Object obj = unmarshaller.unmarshal(new FileInputStream(myFile));

1

예기치 않은 이유 : #파일 경로의 문자

내부 버그로 인해 파일 내용 자체가 100 % 정확하지만 .NET과 같은 파일 이름을 제공하는 경우에도 프롤로그에서 Content is not allowed in prolog 오류 가 나타납니다 C:\Data\#22\file.xml.

이것은 다른 특수 문자에도 적용될 수 있습니다.

확인 방법 : 특수 문자가없는 경로로 파일을 이동했는데 오류가 사라지면이 문제였습니다.


1

오늘도 같은 오류 메시지를 받았습니다. 해결책은 문서를 BOM이있는 UTF-8에서 BOM이없는 UTF-8로 변경하는 것이 었습니다.


나는 같은 문제가 있었다. 파일 형식을 변경하여 문제가 해결되었습니다. 감사!
code_fish

0

공백 대신 탭 문자가 있습니다. '\ t'탭을 교체하면 문제가 해결되었습니다.

전체 문서를 잘라내어 Notepad ++와 같은 편집기에 붙여넣고 모든 문자를 표시합니다.


0

내 문제의 경우 해결책은 독일어 움라우트 (äöü)를 HTML과 동등한 것으로 대체하는 것이 었습니다.


0

다음은 "org.xml.sax.SAXParseException : 프롤로그에서 콘텐츠가 허용되지 않음"예외 위에있는 원인입니다.

  1. 먼저 schema.xsd 및 file.xml의 파일 경로를 확인하십시오.
  2. XML과 XSD (또는 DTD)의 인코딩은 동일해야합니다.
    XML 파일 헤더 : <?xml version='1.0' encoding='utf-8'?>
    XSD 파일 헤더 :<?xml version='1.0' encoding='utf-8'?>
  3. XML 문서 유형 선언 앞에 오는 것이 있다면 : hello<?xml version='1.0' encoding='utf-16'?>

0

"<? xml 앞의 모든 이상한 문자를 삭제하십시오"라는 정신으로 BufferedReader를 통한 입력과 잘 작동하는 Java 코드는 다음과 같습니다.

    BufferedReader test = new BufferedReader(new InputStreamReader(fisTest));
    test.mark(4);
    while (true) {
        int earlyChar = test.read();
        System.out.println(earlyChar);
        if (earlyChar == 60) {
            test.reset();
            break;
        } else {
            test.mark(4);
        }
    }

FWIW, 내가 본 바이트는 (십진수) : 239, 187, 191.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.