【问题标题】:Parse any file type as XML将任何文件类型解析为 XML
【发布时间】:2013-04-25 08:27:43
【问题描述】:

我在 Gradle 脚本中有如下代码 sn-p(语法是 Groovy/Java 的组合):

File file = new File(filename) // Filename is being read from console
def content = file.getText()
Document document = DOMBuilder.parse(new StringReader(content), false, false)

问题是,我正在尝试解析 XML 文件,但扩展名为 xconf(例如 file.xconf)。出于某种原因,当我尝试上面的代码时,我收到以下错误消息(在控制台中):

java.io.FileNotFoundException: <full_path>/file.dtd (No such file or directory)

路径是正确的,但我注意到扩展名突然更改为.dtd。 我注意到文件中有对该文件的.dtd 版本的引用,但我希望解析器忽略它(并停止验证,这就是DOMBuilder.parse() 的第二个参数为假的原因)。我可以更改此行为以成功解析文件吗?

注意:如果可能的话,我也希望能够对(任何)其他文件扩展名做同样的事情。

提前致谢!

【问题讨论】:

    标签: java groovy gradle fileparsing


    【解决方案1】:

    试试这个:

    import groovy.xml.*
    import org.w3c.dom.Document;
    import org.xml.sax.InputSource;
    
    Document parseWithoutDTD( Reader r, boolean validating=false, boolean namespaceAware=true ) {
      FactorySupport.createDocumentBuilderFactory().with { f ->
        f.namespaceAware = namespaceAware
        f.validating = validating
        f.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        f.newDocumentBuilder().with { db ->
          db.parse( new InputSource( r ) )
        }
      }
    }
    
    Document d = new File( filename ).withReader { r ->
      parseWithoutDTD( r )
    }
    

    【讨论】:

    • 到目前为止工作完美。谢谢!
    • 这是一个附带问题:我注意到在这个例子中,namespaceAwareness 是开启的。但是我如何在这里声明命名空间呢?我完全不知道。你可以这样做:f.declareNamespace(...) 然后在方法中添加一个额外的参数吗?
    • 解析时不声明命名空间,在XML文档中声明
    • 那么它会自动识别命名空间吗?我以后可以像file.'namespace:tagname'.getTextContent() 一样解决它吗?非常感谢您迄今为止的帮助。
    • 显然是这样。感谢您提供命名空间证明代码 sn-p!
    【解决方案2】:

    file.xconf xml 必须在 XML 中定义 DTD 引用。打开文件并检查。

    默认情况下,DOM 解析器根据与 XML 关联的 DTD 验证 XML。如果您不想验证,请将验证模式设置为 false。检查 DomBuilder API。

    其他选项是在 XML 中定义 DTD 路径,以便可以从任何地方访问它,或者您也可以注册解析器。我忘了怎么做,但你可以查一下。

    【讨论】:

    • 它确实定义了一个 DTD 引用,但是 - 正如您在问题中看到的 - 验证模式已经设置为 false。
    • 您使用的是哪种 DOMBuilder 实现?似乎即使验证设置为 false,它仍会尝试加载 DTD。我查看了我的代码并找到了它的 EntityResolver。您可以通过实现 EntityResolver 创建自己的解析器。
    • 我正在使用groovy.xml.DOMBuilder
    【解决方案3】:

    DTD 定义了 XML 文档的规则。如果遵循这些规则,则 xml 文档被视为“valid”。 如果您想忽略 DTD 文件(例如因为它不存在),请将解析的验证模式设置为 false。

    【讨论】:

    • 我知道 DTD 是什么,但感谢您花时间澄清。正如上一个答案所评论的那样,验证模式已经设置为false(可以在问题代码中看到)。
    猜你喜欢
    • 2017-02-19
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 2015-05-03
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多