【问题标题】:Groovy XML and the "xml:" namespaceGroovy XML 和“xml:”命名空间
【发布时间】:2012-03-23 20:44:54
【问题描述】:

我正在编写几个脚本来修改 xml 文件。有问题的文件使用 xml:lang 元素。 Groovy (XmlSlurper) 似乎正在插入一个 tag0 命名空间,我不会太介意,但它似乎会破坏以后使用 XmlUtil 的处理。

一个例子:

import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil

String source = """<?xml version='1.0' encoding='UTF-8'?>
<root>
    <one xml:lang="en">First</one>
    <one xml:lang="de">Second</one>
</root>
"""

def root = new XmlSlurper().parseText(source).declareNamespace(xml: "http://www.w3.org/XML/1998/namespace")
println root
String xml = new StreamingMarkupBuilder().bind{ 
    mkp.xmlDeclaration() 
    out << root 
}
println xml
println XmlUtil.serialize(xml)

结果

[Fatal Error] :2:44: The value of the attribute "prefix="xmlns",localpart="tag0",rawname="xmlns:tag0"" is invalid. Prefixed namespace bindings may not be empty.

默认情况下应该存在 xml: 命名空间,我尝试使用 .declareNamespace() 添加它,但似乎没有帮助。我觉得我遗漏了一些明显的东西,但 Google 无法告诉我它是什么。

【问题讨论】:

    标签: groovy xml-serialization xml-parsing


    【解决方案1】:

    几年前发现的this thread,上面写着:

    问题是原始文档使用默认命名空间。

    SMB 通常不使用默认命名空间,因此它发明了一个标签并使用它来显式标记命名空间中的每个元素。就 XML 解析器而言,如何指示名称空间并不重要。然而,有时需要使用默认命名空间有一些美观的原因。

    如果您将mkp.declareNamespace("": "http://java.sun.com/xml/ns/j2ee") 作为构建器闭包的第一行,您应该会得到您想要的输出。

    但是,这似乎不起作用

    我找到的唯一解决方案是让 Slurper 忽略命名空间和验证;

    def root = new XmlSlurper(false,false).parseText(source)
    

    【讨论】:

    • 不幸的是,它对我没有那种效果。我得到与以前完全相同的错误。我在 groovy 1.8.6,你呢?
    • 刚刚再次检查,你是对的......对不起......我会删除这个,然后再试试看我是否可以解决......
    • @ErikAckerman 更新了我的答案以显示我找到的唯一解决方案
    • 完美!这对我来说非常有效,因为它所属的过滤器链已经验证了我们的输入。谢谢!
    • @tim_yates: +1。我有一个类似的problem too,你碰巧得到了其他解决方案吗?
    【解决方案2】:

    将默认命名空间设置为空标签对我有用(未添加“tag0”)。 我使用默认的 XmlSlurper 构造函数来进行命名空间和验证,例如:

    def root = new XmlSlurper().parseText(source).declareNamespace(xml: "http://www.w3.org/XML/1998/namespace")
    

    绑定时,声明空命名空间:

    def writer = new StreamingMarkupBuilder().bind {
        mkp.declareNamespace("": "") //get rid of "tag0"
        mkp.declareNamespace(xml: "http://www.w3.org/XML/1998/namespace") 
        mkp.yield root
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 2020-04-27
      • 2011-08-07
      • 1970-01-01
      • 1970-01-01
      • 2011-04-07
      相关资源
      最近更新 更多