SimpleXML抛出XmlPullParserException,没有理由地引发未终止的实体引用。
SimpleXML抛出XmlPullParserException,没有理由地引发未终止的实体引用。
我对问题的原因已经没有任何想法了..我在Android上使用SimpleXML,它抛出了以下的堆栈跟踪:\n
06-08 13:20:56.450: E/AndroidRuntime(2281): FATAL EXCEPTION: main 06-08 13:20:56.450: E/AndroidRuntime(2281): java.lang.RuntimeException: org.xmlpull.v1.XmlPullParserException: unterminated entity ref (position:TEXT ????T???????????????...@21:133 in java.io.BufferedReader@b6438630) 06-08 13:20:56.450: E/AndroidRuntime(2281): at com.example.stuff.manager.LevelManager.(LevelManager.java:32) 06-08 13:20:56.450: E/AndroidRuntime(2281): at com.example.stuff.fragment.MainMenuFragment.onClick(MainMenuFragment.java:138) 06-08 13:20:56.450: E/AndroidRuntime(2281): at android.view.View.performClick(View.java:2485) 06-08 13:20:56.450: E/AndroidRuntime(2281): at android.view.View$PerformClick.run(View.java:9080) 06-08 13:20:56.450: E/AndroidRuntime(2281): at android.os.Handler.handleCallback(Handler.java:587) 06-08 13:20:56.450: E/AndroidRuntime(2281): at android.os.Handler.dispatchMessage(Handler.java:92) 06-08 13:20:56.450: E/AndroidRuntime(2281): at android.os.Looper.loop(Looper.java:130) 06-08 13:20:56.450: E/AndroidRuntime(2281): at android.app.ActivityThread.main(ActivityThread.java:3683) 06-08 13:20:56.450: E/AndroidRuntime(2281): at java.lang.reflect.Method.invokeNative(Native Method) 06-08 13:20:56.450: E/AndroidRuntime(2281): at java.lang.reflect.Method.invoke(Method.java:507) 06-08 13:20:56.450: E/AndroidRuntime(2281): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 06-08 13:20:56.450: E/AndroidRuntime(2281): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 06-08 13:20:56.450: E/AndroidRuntime(2281): at dalvik.system.NativeStart.main(Native Method) 06-08 13:20:56.450: E/AndroidRuntime(2281): Caused by: org.xmlpull.v1.XmlPullParserException: unterminated entity ref (position:TEXT ????T???????????????...@21:133 in java.io.BufferedReader@b6438630) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.kxml2.io.KXmlParser.exception(KXmlParser.java:273) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.kxml2.io.KXmlParser.error(KXmlParser.java:269) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.kxml2.io.KXmlParser.pushEntity(KXmlParser.java:781) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.kxml2.io.KXmlParser.pushText(KXmlParser.java:849) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.kxml2.io.KXmlParser.nextImpl(KXmlParser.java:354) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.kxml2.io.KXmlParser.next(KXmlParser.java:1378) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.simpleframework.xml.stream.PullReader.read(PullReader.java:105) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.simpleframework.xml.stream.PullReader.next(PullReader.java:89) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.simpleframework.xml.stream.NodeReader.readElement(NodeReader.java:111) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.simpleframework.xml.stream.NodeReader.readRoot(NodeReader.java:85) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.simpleframework.xml.stream.NodeBuilder.read(NodeBuilder.java:84) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.simpleframework.xml.stream.NodeBuilder.read(NodeBuilder.java:71) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.simpleframework.xml.core.Persister.read(Persister.java:562) 06-08 13:20:56.450: E/AndroidRuntime(2281): at org.simpleframework.xml.core.Persister.read(Persister.java:462) 06-08 13:20:56.450: E/AndroidRuntime(2281): at com.example.stuff.manager.LevelManager. (LevelManager.java:27) 06-08 13:20:56.450: E/AndroidRuntime(2281): ... 12 more
\n从以下XML文件加载:\n
\n我使用以下POJO作为XML中内容的容器:\nFruitData.java:\n
@Root public class Fruitdata { @Attribute private Integer id; @Attribute private Integer row; @Attribute private Integer column; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public int getRow() { return row; } public void setRow(int row) { this.row = row; } public int getColumn() { return column; } public void setColumn(int column) { this.column = column; } }
\nFruitDatas.java:\n
@Root public class Fruitdatas { @ElementList private Listfruitdatas; public Fruitdatas() { } public Fruitdatas(@ElementList(name = "fruitdatas") List fruitdatas) { this.fruitdatas = fruitdatas; } public List getFruitdatas() { return fruitdatas; } public void setFruitdatas(List fruitdatas) { this.fruitdatas = fruitdatas; } }
\nLevel.java:\n
@Root public class Level { @Attribute private Long id; @Attribute private Long time; @ElementList private Listfruitdatas; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getTime() { return time; } public void setTime(Long time) { this.time = time; } public List getFruitdatas() { return fruitdatas; } public void setFruitdatas(List fruits) { this.fruitdatas = fruits; } }
\nLevels.java:\n
@Root public class Levels { @ElementList private Listlevels; public Levels() { } public Levels(@ElementList(name = "levels") List levels) { this.levels = levels; } public List getLevels() { return levels; } public void setLevels(List levels) { this.levels = levels; } }
\n加载发生在这里:\n
public LevelManager() { Serializer serializer = new Persister(); Levels levels = null; BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("res/xml/levels.xml"))); levels = serializer.read(Levels.class, br); } catch (Exception e) { Log.e(getClass().getSimpleName(), "Error in deserialization.", e); throw new RuntimeException(e); } finally { if (br != null) { try { br.close(); } catch (IOException e) { } } } if (levels != null) { this.levels = levels.getLevels(); } }
\n我也尝试过只使用InputStream,但是我得到了相同的错误。\n我搜索了答案,但总是发现XML中有未转义的字符。我甚至检查了抛出异常的xml解析器的源代码,但它对我没有多大帮助:\n
723 private final void More ...pushEntity() 724 throws IOException, XmlPullParserException { 725 726 push(read()); // & 727 728 729 int pos = txtPos; 730 731 while (true) { 732 int c = read(); 733 if (c == ';') 734 break; 735 if (c < 128 736 && (c < '0' || c > '9') 737 && (c < 'a' || c > 'z') 738 && (c < 'A' || c > 'Z') 739 && c != '_' 740 && c != '-' 741 && c != '#') { 742 if(!relaxed){ 743 error("unterminated entity ref"); 744 } 745 //; ends with:"+(char)c); 746 if (c != -1) 747 push(c); 748 return; 749 } 750 751 push(c); 752 } 753 754 String code = get(pos); 755 txtPos = pos - 1; 756 if (token && type == ENTITY_REF){ 757 name = code; 758 } 759 760 if (code.charAt(0) == '#') { 761 int c = 762 (code.charAt(1) == 'x' 763 ? Integer.parseInt(code.substring(2), 16) 764 : Integer.parseInt(code.substring(1))); 765 push(c); 766 return; 767 } 768 769 String result = (String) entityMap.get(code); 770 771 unresolved = result == null; 772 773 if (unresolved) { 774 if (!token) 775 error("unresolved: &" + code + ";"); 776 } 777 else { 778 for (int i = 0; i < result.length(); i++) 779 push(result.charAt(i)); 780 } 781 }
\n我不知道!relaxed是什么意思。因此,我完全无法想到如何解决这个问题。\n有人之前遇到过这个问题吗?我可能做错了什么?我甚至连我的XML都是有效的。我认为我也正确地注释了这些类。有什么想法吗?\n编辑:显然我的调试感觉到了,我将缓冲区读入的内容通过System.out发送出去。\n结果:\n
06-08 13:47:51.830: I/System.out(2334): ????T???????????????????????????????????h?????????????????????? ????????????????????????!??????'??????4??????@??????D??????J??????S??????W??????[??????_??????c??????g??????k??????o??????levels??id??time??level??1??400?? 06-08 13:47:51.830: I/System.out(2334): fruitdatas?? fruitdata??0??row??column??2??4??3??5??6??7??8??9??????$??????????????????????????????????????????????????L???????????????????????????????????????????????????????????????????????????????????????????????$????????????????????????????????????????????????$????????????????????????????????????????????????$??????????????????????????????????????????????????????????????????????????????????????????????????????????????????$???????????????????? ?????????????????????????????????????????????????????????????????????????????????????? ????????$???????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????? ??????????????????????$?????? 06-08 13:47:51.830: I/System.out(2334): ??????????????????????????????????????????$??????????????????????????????????????????????????????????????????????????????????????????????????????????????$???????????????????? ?????????????????????????????????????????????????????????????????????????????????????? ????????$????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ?????????????????????????????????????????????????????????????????????????????????????? 06-08 13:47:51.830: I/System.out(2334): ??????????????????????????????????????????????????????????????????????????????????????
\n我将尝试弄清楚为什么从流中读取的XML是无意义的....
SimpleXML throws XmlPullParserException, unterminated entity ref for no reason
最近我遇到了一个问题,经过我的调试,我终于找到了解决方法。原来,使用以下代码读取数据是一个非常糟糕的主意。
br = new BufferedReader(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream("res/xml/levels.xml")));
解决方法是将XML文件放入/res/raw文件夹中,并使用原始资源方式打开它们。
public LevelManager(Context context) { Serializer serializer = new Persister(); Levels levels = null; BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(context.getResources().openRawResource(R.raw.levels))); levels = serializer.read(Levels.class, br); } catch (Exception e) { Log.e(getClass().getSimpleName(), "Error in deserialization.", e); throw new RuntimeException(e); } finally { if (br != null) { IOUtils.closeQuietly(br); } } }
这样,文件的内容就可以正确地读取了。
希望这个解决方法能够帮助到其他人,不要再浪费时间在这个问题上了。
另外,我还需要添加`inline=true`,否则根据我的XML结构,它找不到数据。但这与问题没有直接关系。