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

Digester.getParser:
java.lang.UnsupportedOperationException:该解析器不支持规范“未知”版本“ 0.0”

java.lang.NullPointerException
03-29 11:24:02.590:
W / System.err(17018):位于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>

最佳答案

查看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,而是自己创建一个-这样您就可以避免调用看起来像这样的setSchema可能是问题所在:

// 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...


目前不进行任何android开发,因此无法对其进行测试,但是看起来它可以工作...

更新2

这样看来就解决了架构问题,您现在所看到的似乎是一个单独的类加载器问题。这实际上是一个单独的问题,但这是一个可能的黑客……绕过banutils内省,仅使用自定义规则自己处理属性。这仅是真正的实际操作,因为示例中的XML相当简单-复杂得多的方法都无法使用:

final List<Prefixe> list = new ArrayList<>();
final SAXParserFactory factory = SAXParserFactory.newInstance();

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

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"));
    list.add(prefixe);
  }
});

digester.parse(...);


请注意,您似乎在某个地方遇到了类加载器问题(除非您已经在某种程度上削弱了beanutils的版本?),我强烈建议您尝试使问题归根到底,因为它们可能会再次咬住您一次又一次...

祝好运!

10-06 03:40