当前位置: 首页 > 面试题库 >

查找XML文档中的所有名称空间声明-xPath 1.0与xPath 2.0

周承天
2023-03-14
问题内容

作为Java 6应用程序的一部分,我想在XML文档中找到所有名称空间声明,包括所有重复项。

编辑 :根据马丁的要求,这是我正在使用的Java代码:

XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
XPathExpression xPathExpression = xPathExpression = xPath.compile("//namespace::*"); 
NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDomDocument, XPathConstants.NODESET);

假设我有这个XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:ele="element.com" xmlns:att="attribute.com" xmlns:txt="textnode.com">
    <ele:one>a</ele:one>
    <two att:c="d">e</two>
    <three>txt:f</three>
</root>

为了找到所有名称空间声明,我 使用xPath 1.0 将此xPath语句应用于XML文档:

//namespace::*

它找到4个名称空间声明,这是我期望的(和期望的):

/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace

但是,如果我 改用xPath 2.0 ,则会得到16个名称空间声明(每个先前的声明4次),这不是我期望的(或期望的):

/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com
/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/@xmlns:att - attribute.com
/root[1]/@xmlns:ele - element.com
/root[1]/@xmlns:txt - textnode.com

即使当我使用xPath语句的非缩写版本时,也会看到相同的区别:

/descendant-or-self::node()/namespace::*

在oXygen中测试过的各种XML解析器(LIBXML,MSXML.NET,Saxon)中都可以看到它。( 编辑:
正如我稍后在评论中提到的那样,该陈述是不正确的。尽管我认为我正在测试各种XML解析器,但实际上并非如此。)

问题1: 为什么从xPath 1.0到xPath 2.0有区别?

问题2: 使用xPath 2.0是否有可能/合理地获得预期的结果?

提示:distinct-values()在xPath 2.0中使用该函数将 不会
返回期望的结果,因为我希望所有名称空间声明,即使同一名称空间被声明两次。例如,考虑以下XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <bar:one xmlns:bar="http://www.bar.com">alpha</bar:one>
    <bar:two xmlns:bar="http://www.bar.com">bravo</bar:two>
</root>

理想的结果是:

/root[1]/@xmlns:xml - http://www.w3.org/XML/1998/namespace
/root[1]/bar:one[1]/@xmlns:bar - http://www.bar.com
/root[1]/bar:two[1]/@xmlns:bar - http://www.bar.com

问题答案:

我认为这将获得所有名称空间,而不会重复:

for $i in 1 to count(//namespace::*) return 
if (empty(index-of((//namespace::*)[position() = (1 to ($i - 1))][name() = name((//namespace::*)[$i])], (//namespace::*)[$i]))) 
then (//namespace::*)[$i] 
else ()


 类似资料:
  • 使用xslt 1.0(BizTalk 2016)我正在寻找一种通用的方法来选择任何有效的xml文档的命名空间 例如,我有以下xml文档: 假设根元素的值可以是任何东西,那么选择名称空间值的xpath是什么http://www.random.com/bo/request/portfolioactivation 我原本希望“/*/@xmlns”能起作用,但事实并非如此。

  • 问题内容: 我正在寻找可以构造使用名称空间的XML文档的Java代码。我似乎无法使用我最喜欢的工具找到任何东西,因此希望有人可以帮助我。 问题答案: 我不确定您要做什么,但是我将jdom用于大多数xml问题,并且它支持名称空间(当然)。 代码: 产生以下xml: 其中应包含您需要的一切。希望能有所帮助。

  • 问题内容: 如何在JavaScript中创建名称空间,以使我的对象和函数不会被其他同名对象和函数覆盖?我使用了以下内容: 有没有更优雅或更简洁的方法? 问题答案: 我喜欢这个:

  • 我对C++不是很熟悉,这是我第一次使用的不仅仅是名称空间std。下面的有什么区别? VS 在这两个之后,我现在似乎可以创建一个MyClass对象了。一种方式比另一种好吗?另外,如果我都不这样做,我还可以通过每次需要时在MyNamespace::MyClass之前附加MyClass来引用MyClass吗? 接下来,如果我使用第二个选项转发declare,我还需要吗?在我(不是很好)的理解中,在C++

  • 我有一个有趣的情况,我的XML编辑器(Oxygen,使用Xerces XML处理器)需要根标签上的前缀,但是我的JAXB XML Marshaller(也是基于Xerces的)不需要根标签上的前缀。我正在试图理解这种情况。 首先是2个模式文件: ns1.xsd ns2。xsd 目前的氧气释放(16.1)需要我称之为“版本1”的东西 版本1 如果我像下面的示例(版本1)那样删除前缀: 版本2 氧气抱

  • 我正在尝试选择一个特定的