Обработка 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)" />
Другие вопросы по тегам