首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >默认情况下,XmlParser和XmlSlurper名称空间是否可以识别?

默认情况下,XmlParser和XmlSlurper名称空间是否可以识别?
EN

Stack Overflow用户
提问于 2015-10-29 15:46:55
回答 2查看 1.4K关注 0票数 3

在用How to read values from XML Request and write into XML Response using Groovy?XmlParser回答与名称空间(SOAP)相关的问题时,我意识到我实际上无法判断它们在默认情况下是否是非命名空间感知的。

虽然文档这么说(默认情况下不具有名称空间感知的):

XmlSlurper

XmlSlurper () 创建一个非验证和非命名空间感知的XmlSlurper,它不允许文档中的DOCTYPE声明。

XmlParser

XmlParser () 创建一个非验证和非命名空间感知的XmlParser,它不允许文档中的DOCTYPE声明。

代码正好相反(默认情况下,名称空间可以识别):

https://github.com/groovy/groovy-core/blob/master/subprojects/groovy-xml/src/main/java/groovy/util/XmlSlurper.java

代码语言:javascript
复制
public XmlSlurper() throws ParserConfigurationException, SAXException {
    this(false, true);
}

https://github.com/groovy/groovy-core/blob/master/subprojects/groovy-xml/src/main/java/groovy/util/XmlParser.java

代码语言:javascript
复制
public XmlParser() throws ParserConfigurationException, SAXException {
    this(false, true);
}

我还发现这个answer声称默认情况下XMLSlurper是非命名空间感知的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-05 20:04:48

在Groovy 2.4.6中,文档是错误的:

代码语言:javascript
复制
/**
 * Creates a non-validating and non-namespace-aware <code>XmlSlurper</code> which does not allow DOCTYPE declarations in documents.
 *
 * @throws ParserConfigurationException if no parser which satisfies the requested configuration can be created.
 * @throws SAXException for SAX errors.
 */
public XmlSlurper() throws ParserConfigurationException, SAXException {
    this(false, true);
}

它实际上创建了一个命名空间感知解析器(第二个参数为true)。

在我报告的名称空间前缀处理不当的地方还有一个bug:https://issues.apache.org/jira/browse/GROOVY-7781。幸运的是,另一个用户发布了一个PR来修复。有人应该进行公关来解决文档问题,这已经给我自己和其他人造成了多次的混乱。

票数 1
EN

Stack Overflow用户

发布于 2015-10-29 15:48:12

我认为文档是错误的,默认情况下,XmlSlurperXmlParser是命名空间感知的:

代码语言:javascript
复制
def text = '''<person xmlns:city="http://localhost/">
    <name>jalopaba</name>
    <city:name>Valladolid</city:name>
</person>'''

// XmlSlurper is namespace aware, since new XmlSlurper() --> new XmlSlurper(false, true)
def slurped_person = new XmlSlurper().parseText(text)
assert 'jalopabaValladolid' == slurped_person.name.text() // :name and :name from city
assert 'jalopaba' == slurped_person.':name'.text() // aware of default namespace
assert '' == slurped_person.'city:name'.text() // city namespace not declared

// but you need to make the resulting GPathResult aware of the concrete namespace
slurped_person = new XmlSlurper().parseText(text).declareNamespace([city: 'http://localhost/'])
assert 'jalopabaValladolid' == slurped_person.name.text() // :name and :name from city
assert 'jalopaba' == slurped_person.':name'.text() // aware of default namespace
assert 'Valladolid' == slurped_person.'city:name'.text() // city namespace declared

// If you make XmlSlurper not namespace aware, it uses the whole element string
slurped_person = new XmlSlurper(false, false).parseText(text)
assert 'jalopaba' == slurped_person.name.text() // just element 'name'
assert '' == slurped_person.':name'.text() // not aware of default namespace
assert 'Valladolid' == slurped_person.'city:name'.text() // using the whole element string (it seems to be namespace aware, but it's not)

// And when it is not namespace aware, nothing changes declaring namespaces
slurped_person = new XmlSlurper(false, false).parseText(text).declareNamespace([city: 'http://localhost/'])
assert 'jalopaba' == slurped_person.name.text() // just element 'name'
assert '' == slurped_person.':name'.text() // not aware of default namespace
assert 'Valladolid' == slurped_person.'city:name'.text() // using the whole element string (it seems to be namespace aware, but it's not)

def c = new Namespace('http://localhost/', 'city')
assert c.name instanceof QName // => new QName('http://localhost/', 'name', 'city')

// XmlParser is namespace aware, since new XmlParser() --> new XmlParser(false, true)
def parsed_person = new XmlParser().parseText(text)
assert parsed_person.toString() == 'person[attributes={}; value=[name[attributes={}; value=[jalopaba]], {http://localhost/}name[attributes={}; value=[Valladolid]]]]'
assert 'jalopaba' == parsed_person.name.text() // default namespace
assert 'jalopaba' == parsed_person[new QName('name')].text() // default namespace
assert 'jalopabaValladolid' == parsed_person[new QName('http://localhost/', 'name')].text() // aware of namespace and empty string as prefix
assert 'Valladolid' == parsed_person[new QName('http://localhost/', 'name', 'it_does_not_matter')].text() // aware of namespace, prefix does not matter
assert '' == parsed_person[new QName('http://wrong_namespace/', 'name', 'city')].text() // aware of namespace, wrong URI with good prefix gets nothing
assert 'Valladolid' == parsed_person[c.name].text()
assert 'Valladolid' == parsed_person.'city:name'.text() // using the whole element string

// With XmlParser not namespace aware...
parsed_person = new XmlParser(false, false).parseText(text)
assert parsed_person.toString() == 'person[attributes={xmlns:city=http://localhost/}; value=[name[attributes={}; value=[jalopaba]], city:name[attributes={}; value=[Valladolid]]]]'
assert 'jalopaba' == parsed_person.name.text()
assert 'jalopaba' == parsed_person[new QName('name')].text()
assert 'jalopaba' == parsed_person[new QName('http://localhost/', 'name')].text() // ignores namespace, only uses 'name' string
assert '' == parsed_person[new QName('http://localhost/', 'name', 'wrong_prefix')].text() // not aware of namespace, the only important thing is prefix
assert 'Valladolid' == parsed_person[new QName('http://wrong_namespace/', 'name', 'city')].text() // wrong namespace but not aware, the only important thing is prefix
assert 'Valladolid' == parsed_person[c.name].text()
assert 'Valladolid' == parsed_person.'city:name'.text()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33418826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档