我有一个xml文档,其中有固定的结构但深度不同,例如: -
- 它有主节点
<project>
。- 它具有可以重复多次的子节点
醇><namespace>
。在<namespace>
之前或之后可能会出现一些新标签。
<project>
<newtag>
<namespace>
<namespace>
..........
</namespace>
</namespace>
</newtag>
</project>
- 在多个命名空间之后,还有两个我感兴趣的标记
醇><querySubject>
和<queryItem>
我正在使用特定的XPATH在queryItem标签中搜索文本: -
/project/namespace/namespace/querySubject/queryItem[contains(., 'searchTerm')]/ancestor-or-self::*/name
我的Xpath适用于下面给出的特定结构: -
<project>
<namespace>
<name locale="en">Test</name>
<lastChanged>2016-01-12T12:42:46</lastChanged>
<namespace>
<name locale="en">Database Layer</name>
<querySubject status="valid">
<name locale="en">qskxyz</name>
<queryItem>
<name locale="en">qixyz</name>
<hello>searchTerm</hello>
</queryItem>
</querySubject>
</namespace>
</namespace>
<namespace>
<name locale="en">Test</name>
<lastChanged>2016-01-12T12:42:46</lastChanged>
<namespace>
<name locale="en">Database Layer</name>
<querySubject status="valid">
<name locale="en">qsxyz</name>
<queryItem>
<name locale="en">myName</name>
<hello>...Hi there..</hello>
</queryItem>
</querySubject>
</namespace>
</namespace>
</project>
但如果有如上所述的变化,则无法正常工作。任何建议
编辑1。
我的观察中有一些错过
我的实际项目标签是
<project containsDynamicContent="false" xmlns="http://www.developer.cognos.com/schemas/bmt/60/7" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.developer.cognos.com/schemas/bmt/60/7 BMTModelSpecification.xsd">
然而,在开发中我采用简单的<project></project>
这会影响我的Xpath无效。 我在Xpath下面尝试过的任何建议,但这也没有用,我无法更改我的xml标签.. 我已经尝试过这个xpath: -
//namespace//querySubject/queryItem[contains(.,'searchTerm')]/ancestor-or-self::*/name
答案 0 :(得分:1)
基本上,XPath表达式是:
/x:project//x:namespace//x:querySubject/x:queryItem[contains(.,'searchTerm')]/ancestor-or-self::*/x:name
然后,您需要将名称空间http://www.developer.cognos.com/schemas/bmt/60/7
与前缀x
相关联。
我将以Java(1.7)为例给您留下一个片段。这会向NamespaceContext
注册XPath表达式,该表达式解析前缀的名称空间(在本例中为x
)。该片段是一个例子,它甚至不检查传递给NamespaceContext.getNamespaceURI
的前缀。典型的实现使用映射将URI映射到前缀。
其他开发环境应该具有类似的功能。
import java.io.StringReader;
import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.*;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class XPathInXmlns {
private static final String xml=
"<project containsDynamicContent=\"false\" xmlns=\"http://www.developer.cognos.com/schemas/bmt/60/7\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.developer.cognos.com/schemas/bmt/60/7 BMTModelSpecification.xsd\">"+
" <namespace>"+
" <name locale=\"en\">Test</name>"+
" <lastChanged>2016-01-12T12:42:46</lastChanged>"+
" <namespace>"+
" <name locale=\"en\">Database Layer</name>"+
" <querySubject status=\"valid\">"+
" <name locale=\"en\">qskxyz</name>"+
" <queryItem>"+
" <name locale=\"en\">qixyz</name>"+
" <hello>searchTerm</hello>"+
" </queryItem>"+
" </querySubject>"+
" </namespace>"+
" </namespace>"+
" <namespace>"+
" <name locale=\"en\">Test</name>"+
" <lastChanged>2016-01-12T12:42:46</lastChanged>"+
" <namespace>"+
" <name locale=\"en\">Database Layer</name>"+
" <querySubject status=\"valid\">"+
" <name locale=\"en\">qsxyz</name>"+
" <queryItem>"+
" <name locale=\"en\">myName</name>"+
" <hello>...Hi there..</hello>"+
" </queryItem>"+
" </querySubject>"+
" </namespace>"+
" </namespace>"+
" </project>";
private static final String xpathExpr=
"/x:project//x:namespace//x:querySubject/x:queryItem[contains(.,'searchTerm')]/ancestor-or-self::*/x:name/text()";
public static void main(String[] args) {
try {
XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
@Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
@Override
public String getPrefix(String namespaceURI) {
return null;
}
@Override
public String getNamespaceURI(String prefix) {
return "http://www.developer.cognos.com/schemas/bmt/60/7";
}
});
XPathExpression expr = xpath.compile(xpathExpr);
NodeList nodeList = (NodeList) expr.evaluate(new InputSource(new StringReader(xml)),XPathConstants.NODESET);
for( int i = 0; i != nodeList.getLength(); ++i )
System.out.println(nodeList.item(i).getNodeValue());
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
}
输出:
Test
Database Layer
qskxyz
qixyz