我需要使用NAME =“CONTENTTYPE”读取所有处理指令,我想读取@VALUE并连接所有值并返回XQuery / XPath。
我的XML:
<REG >
<MARKER MRKEID="SLREG:7.1" MRKTYPE="LD DU" MRKDATE="20130909" MRKTIME="10402688"/>
<?METADATA NAME="CONTENTTYPE" VALUE="STATUTE"?>
<?METADATA NAME="CONTENTTYPE" VALUE="LEGISLATIVEDOCUMENT"?>
<?METADATA NAME="CONTENTTYPE" VALUE="PRIMARYSOURCE"?>
<?METADATA NAME="SLTAXTYPE" VALUE="PRIMARYSOURCE"?>
</REG>
ExpectedOutput:
STATUTE
LEGISLATIVEDOCUMENT
PRIMARYSOURCE
感谢您在编写XQuery / XPath以获得上述输出方面的帮助。
先谢谢。
此致 哈
答案 0 :(得分:0)
//processing-instruction('METADATA')[matches(., 'NAME="CONTENTTYPE" VALUE="[^"]*"')]/replace(substring-after(., 'VALUE="'), '"', '')
。这是XPath 2.0。
答案 1 :(得分:0)
使用JDOM标记帮助我找到了这个。
很长的回答...... XPath没有原生的能力来解析向ProcessingInstructions添加“属性”的“标准”方式。如果你想将值连接作为单个XPath表达式的一部分,我认为你运气不好......实际上,Martin的答案看起来很有希望,但它会返回一些String值,而不是ProcessingInsructions。 JDOM 2.x将需要XPath.compile(...)上的Filters.string(),你将获得List<String>
结果到path.evaluate(doc)....我认为这样做更简单它在XPath之外。特别是考虑到使用Saxon库和JDOM 2.x
至于以编程方式进行,JDOM 2.x有很大帮助。以您的示例XML为例,我采用了两种方式,第一种方法是在XPath结果集上使用自定义Filter。第二种方式实际上做了同样的事情,但在循环中进一步限制了PI。
public static void main(String[] args) throws Exception {
SAXBuilder saxb = new SAXBuilder();
Document doc = saxb.build(new File("data.xml"));
// This custom filter will return PI's that have the NAME="CONTENTTYPE" 'pseudo' attribute...
@SuppressWarnings("serial")
Filter<ProcessingInstruction> contenttypefilter = new AbstractFilter<ProcessingInstruction>() {
@Override
public ProcessingInstruction filter(Object obj) {
// because we know the XPath expression selects Processing Instructions
// we can safely cast here:
ProcessingInstruction pi = (ProcessingInstruction)obj;
if ("CONTENTTYPE".equals(pi.getPseudoAttributeValue("NAME"))) {
return pi;
}
return null;
}
};
XPathExpression<ProcessingInstruction> xp = XPathFactory.instance().compile(
// search for all METADATA PI's.
"//processing-instruction('METADATA')",
// The XPath will return ProcessingInstruction content, which we
// refine with our custom filter.
contenttypefilter);
StringBuilder sb = new StringBuilder();
for (ProcessingInstruction pi : xp.evaluate(doc)) {
sb.append(pi.getPseudoAttributeValue("VALUE")).append("\n");
}
System.out.println(sb);
}
第二种方法使用更简单和预定义的Filters.processingInstruction()
,然后手动进行额外的过滤....
public static void main(String[] args) throws Exception {
SAXBuilder saxb = new SAXBuilder();
Document doc = saxb.build(new File("data.xml"));
XPathExpression<ProcessingInstruction> xp = XPathFactory.instance().compile(
// search for all METADATA PI's.
"//processing-instruction('METADATA')",
// Use the pre-defined filter to set the generic type
Filters.processinginstruction());
StringBuilder sb = new StringBuilder();
for (ProcessingInstruction pi : xp.evaluate(doc)) {
if (!"CONTENTTYPE".equals(pi.getPseudoAttributeValue("NAME"))) {
continue;
}
sb.append(pi.getPseudoAttributeValue("VALUE")).append("\n");
}
System.out.println(sb);
}