android with commons-digester java.lang.UnsupportedOperationException:这个解析器不支持规范" Unknown"版本" 0.0"

时间:2015-03-29 09:39:25

标签: android xml apache-commons-digester

我必须使用commons-digester.jar来处理android中的xml文件 实际上这是一个开源程序,它使用commons-digester.jar进行Java中的xml处理 我需要更改它以支持Android 但是这个错误发生了:

Digester.getParser: java.lang.UnsupportedOperationException:此解析器不支持规范“Unknown”version“0.0”

显示java.lang.NullPointerException 03-29 11:24:02.590: W / System.err(17018):at org.apache.commons.digester3.Digester.getXMLReader(Digester.java:790) 03-29 11:24:02.590:W / System.err(17018):at org.apache.commons.digester3.Digester.parse(Digester.java:1588) 03-29 11:24:02.590:W / System.err(17018):at org.apache.commons.digester3.Digester.parse(Digester.java:1557) 03-29 11:24:02.590:W / System.err(17018):at com.tashkeel.android.utilities.alkhalil.DbLoader.LoadPrefixes(DbLoader.java:65) 03-29 11:24:02.590:W / System.err(17018):at com.tashkeel.android.utilities.alkhalil.analyse.Analyzer。(Analyzer.java:64) 03-29 11:24:02.600:W / System.err(17018):at com.tashkeel.android.MainActivity $ 1.run(MainActivity.java:80) 03-29 11:24:02.600:W / System.err(17018):at java.lang.Thread.run(Thread.java:856) 03-29 11:24:03.240:W / System.err(17018):

以及使用commons-digester的代码示例

 Digester digester = new Digester();
 digester.addObjectCreate("prefixes", Lists.class);
 digester.addObjectCreate("prefixes/prefixe", Prefixe.class);
  digester.addSetProperties("prefixes/prefixe", "unvoweledform",     
           "unvoweledform");
 digester.addSetProperties("prefixes/prefixe", "voweledform",

  "voweledform");
  digester.addSetProperties("prefixes/prefixe", "desc", "desc");

 digester.addSetProperties("prefixes/prefixe", "classe", "classe");

 digester.addSetNext("prefixes/prefixe", "addPrefixe");

 return (Lists)digester.parse(pref);

我尝试解析的xml的一部分:

  <?xml version="1.0" encoding="utf-8" ?>
<prefixes>
    <prefixe unvoweledform="" voweledform="" desc="" classe="C1">
    </prefixe>
    <prefixe unvoweledform="و" voweledform="وَ" desc="حرف العطف" classe="C1">
        </prefixe>
    <prefixe unvoweledform="ف" voweledform="فَ" desc="حرف العطف أو الاستئناف" 
classe="C1">
     </prefixe>
    </prefixes>

2 个答案:

答案 0 :(得分:1)

查看Digester的源代码,它的代码如下:

SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware( namespaceAware );
factory.setXIncludeAware( xincludeAware );
factory.setValidating( validating );
factory.setSchema( schema );

然后检查JavaDoc以查找SAXParserFactory#setSchema

  

解析器必须能够使用任何Schema实现......   抛出:UnsupportedOperationException - 当实现没有时   覆盖此方法。

所以我的猜测是你的代码接收的SAXParserFactory实现不支持某种方式的模式。

SAXParserFactory.html#newInstance doco中有一些疑难解答提示,但您也可以通过以下方式找到返回的确切解析器类(不需要Digester代码):

SAXParserFactory factory = SAXParserFactory.newInstance();
System.err.println("SAXParserFactory class is " + factory.getClass().getName());

另外,来自Android SAXParserFactory doco

  

UnsupportedOperationException为了向后兼容,何时   使用了早期版本的JAXP的实现,这个例外   将被抛出。

因此,您可能需要检查您正在使用的JAXP等版本。

<强>更新

鉴于你不需要模式,你可以试试这个可能有效......而不是让沼气池为你创建SAXParserFactory,自己创建一个 - 这样你就可以避免调用{{ 1}}看起来可能是问题所在:

setSchema

目前没有进行任何Android开发,因此无法对此进行测试,但看起来它可以正常工作......

更新2

所以看起来它修复了架构问题,而你现在看来是一个单独的类加载器问题。这实际上是一个单独的问题,但这是一个可能的黑客......绕过banutils内省,只是自己用自定义规则处理属性。这只是非常实用,因为在你的例子中你有相当简单的XML - 任何更复杂的东西,这种方法变得不可行:

// create your own SAXParserFactory, but don't call any of the set methods unless you explicitly need to
final SAXParserFactory myfactory = SAXParserFactory.newInstance();

//myfactory.setNamespaceAware( namespaceAware );
//myfactory.setXIncludeAware( xincludeAware );
//myfactory.setValidating( validating );
//myfactory.setSchema( schema );

// create your own Digester and override the getFactory method to return your own factory
Digester digester = new Digester() {
  @Override
  public SAXParserFactory getFactory() {
    return myfactory;
  }
};

// use this digester as normal for the rest of your code...

请注意,看起来你的某个地方存在类加载器问题(除非你的beanutils版本在某种程度上已经削弱了?)我强烈建议你尽量找到它们的底部回来再次咬你......

祝你好运!

答案 1 :(得分:0)

经过@Barney回答的一点点修改后的最终答案 从addRule函数中的函数add前缀返回列表:

    public Lists LoadPrefixes() throws Exception {

    InputStream   in = assetManager.open("db/prefixes.xml");

   final SAXParserFactory factory = SAXParserFactory.newInstance();

    Digester digester = new Digester() {
      @Override
      public SAXParserFactory getFactory() {
         //System.out.println("using custom factory...");
        return factory;
      }
    };

      final Lists Lists_ob=new Lists();


    digester.addRule("prefixes/prefixe", new Rule() {
      @Override
      public void begin(String namespace, String name, Attributes attributes) throws Exception {
        Prefixe prefixe = new Prefixe();
        prefixe.setUnvoweledform(attributes.getValue("unvoweledform"));
        prefixe.setVoweledform(attributes.getValue("voweledform"));
        prefixe.setDesc(attributes.getValue("desc"));
        prefixe.setClasse(attributes.getValue("classe"));
        Lists_ob.addPrefixe(prefixe);

      }
    });


      digester.parse(in);

     return Lists_ob;

}

这是代码最初在Lists.class中

 private List prefixes = new LinkedList();

   public void addPrefixe(Prefixe p) {
    prefixes.add(p);
}