Обработка XSLT с Java: передача содержимого XML в параметре
Я хотел бы передать параметр, содержащий содержимое XML, при обработке XSLT. Вот мой код:
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
File xmlFile = new File(xmlFilePath);
File xsltFile = new File(xslFilePath);
Source xmlSource = new StreamSource(xmlFile);
Result result = new StreamResult(System.out);
TransformerFactory transFact = TransformerFactory.newInstance();
Transformer trans = transFact.newTransformer(xsltSource);
trans.setParameter("foo", "<bar>Hello1</bar><bar>Hello2</bar>");
trans.transform(xmlSource, result);
Затем я хотел бы выбрать значения, содержащиеся в теге 'bar' в моем XSL-файле.
<xsl:param name="foo"/>
...
<xsl:value-of select="$foo//foo[1]" />
Но это не работает, я получаю это сообщение об ошибке:
org.apache.xpath.objects.XString cannot be cast to org.apache.xpath.objects.XNodeSet
Поэтому я думаю, что должен передать объект XML в мой метод setParameter, но какой именно? Я не могу найти простой пример, как создать объект XNodeSet...
Как я могу это сделать? Благодарю.
3 ответа
Если вы используете Saxon, самое простое решение - передать StreamSource в качестве значения параметра:
setParameter("foo", new StreamSource(new StringReader("<bar>baz</bar>")));
Но это может не работать с другими процессорами: JAXP оставляет его определяемым реализацией, какие виды Object могут быть переданы в качестве значений параметров.
Возможно, вы захотите проверить документацию вашего процессора XSLT, какие типы параметров он разрешает и позволяет ли он передавать в узле, а не в строке. Если я понимаю, http://www.saxonica.com/html/documentation/using-xsl/embedding/jaxp-transformation.html и http://www.saxonica.com/html/documentation/javadoc/net/sf/saxon/jaxp/TransformerImpl.html правильно, тогда Saxon позволяет передавать узлы в виде его NodeInfo
,
Если вы используете Xalan (встроенная реализация в Java JDK), то передайте «URI» в качестве значения параметра, которое представляет собой любое значение, которое вы хотите сопоставить на следующем шаге:
setParameter("foo", "myxml")
Теперь определите a на трансформаторе (пример на Kotlin, но java-перевод прост):
val transformer = factory.newTransformer(...)
transformer.setURIResolver { href, base ->
when (href) {
"myxml" -> StreamSource(StringReader("<bar>baz</bar>"))
else -> error("Cannot resolve href $href")
}
}
Определите столько URI и отображений, чтобыSource
по мере необходимости.
В таблице стилей используйтеdocument
функция для передачи параметра строки URI пользовательскомуURIResolver
и преобразовать его в документ XML:
<xsl:param name="foo" />
<xsl:param name="fooDoc" select="document($foo)" />