Тегирование с помощью JDOM помогло мне найти это.
Приходит длинный ответ ... XPath не имеет встроенной возможности анализировать «стандартный» способ добавления «атрибутов» в ProcessingInstructions. Если вы хотите выполнить объединение значений как часть одного выражения XPath, я думаю, вам не повезло... на самом деле ответ Мартина выглядит многообещающе, но он вернет ряд значений String, а не ProcessingInsructions. JDOM 2.x потребуется Filters.string() в XPath.compile(...), и вы получите результат List<String>
для path.evaluate(doc).... Я думаю, что проще сделать это вне XPath. Особенно с учетом того, что поддержка XPath2.0 ограничена при использовании библиотеки Saxon с JDOM 2.x.
Что касается программного обеспечения, то JDOM 2.x очень помогает. Взяв ваш пример XML, я сделал это двумя способами, первый способ использует настраиваемый фильтр в наборе результатов XPath. Второй способ фактически делает то же самое, но ограничивает 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);
}
person
rolfl
schedule
25.10.2013
METADATA
и, например.NAME="CONTENTTYPE" VALUE="STATUTE"
— это неструктурированные данные, которые вам нужно будет проанализировать с помощью собственного кода.@VALUE
не будет работать, он выбирает атрибут с таким именем, но только узлы элементов имеют атрибуты, а инструкции по обработке - нет. - person Martin Honnen   schedule 25.10.2013