查找重复的XML元素名称(带变量的xPath)

时间:2011-07-06 12:31:39

标签: java xml xpath

我在我的JAVA项目中使用XPATH 1.0解析器和CLiXML,我正在尝试设置CLiXML约束规则文件。

如果特定子项下存在重复的元素名称,我想显示错误。

例如

<parentNode version="1">
    <childA version="1">
        <ignoredChild/>
    </childA>
    <childB version="1">
        <ignoredChild/>
    </childB>
    <childC version="4">
        <ignoredChild/>
    </childC>
    <childA version="2">
        <ignoredChild/>
    </childA>
    <childD version="6">
        <ignoredChild/>
    </childD>
</parentNode>

childA出现不止一次,所以我会对此显示错误。

注意:我只想“检查/计算”元素名称,而不是内部属性或元素的子元素。

我尝试过的.clx规则文件中的代码是:

<forall var="elem1" in=".//parentNode/*">
    <equal op1="count(.//parentNode/$elem1)" op2="1"/>
</forall>

但这不起作用,我收到错误:

Caused by: class org.jaxen.saxpath.XPathSyntaxException: count(.//PLC-Mapping/*/$classCount: 23: Expected one of '.', '..', '@', '*', <QName>

因为我希望代码检查每个子名称并使用子名称的名称运行另一个xPath查询 - 如果计数大于1,那么它应该给出错误。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

尝试获取具有适当路径表达式的子节点列表,并检查该列表中的重复项:

   XPathExpression xPathExpression = xPath.compile("//parentNode/*");
   NodeList children = (NodeList) xPathExpression.evaluate(config, XPathConstants.NODESET);

   for (int i = 0; i < children.getLength(); i++) {
   // maintain hashset of clients here and check if element is already there
   }

答案 1 :(得分:1)

使用单个XPath 1.0表达式无法做到这一点(请参阅我今天回答的 this similar question )。

这是一个单独的XPath 2.0表达式(如果你可以使用XPath 2.0):

/*/*[(for $n in name() 
      return count(/*/*[name()=$n]) 
      )
     >1
     ]

这将选择所有作为XML文档顶部元素的子元素并且多次出现的元素。