XSLT-поиск с использованием ключа, когда XSLT Source обрабатывается из String в Java - PullRequest
0 голосов
/ 15 июня 2011

Я пытаюсь обработать поиск XSLT - принимая входные данные XSLT в виде строки вместо файла после определенных изменений. Все работает хорошо, если я записываю измененный XSLT в виде файла и снова читаю его для преобразования, но когда я обрабатываю это как строку, поиск не работает.

Метод, выполняющий преобразование, описан ниже.

    public static void transform(File inputXmlfile, String outputXmlFileName) throws ParserConfigurationException, SAXException, IOException, TransformerException {

    DocumentBuilderFactory docBuildFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder parser = docBuildFactory.newDocumentBuilder();
    Document document = parser.parse(inputXmlfile);

    TransformerFactory xformFactory = TransformerFactory.newInstance();

    String xsltString="<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
    "<xsl:stylesheet version=\"1.0\""+
    " xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:c=\"http://myDomain.com/classifications.data\">"+
    "<xsl:output method=\"xml\" />"+
    "<xsl:key name=\"classification-lookup\" match=\"c:classification\" use=\"c:id\" /> <xsl:template match=\"/\"><listings xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://local.google.com/local_feed.xsd\"><language>en</language><datum>WGS84</datum>" +
    "<xsl:for-each select=\"BusinessListings/BusinessListing\"><listing><id><xsl:value-of select=\"id\" /></id><xsl:apply-templates /></listing></xsl:for-each></listings></xsl:template><xsl:template match=\"classificationId\"><xsl:variable name=\"currentId\" select=\".\" />" +
    "<xsl:for-each select=\"document('')\"><category><xsl:value-of select=\"key('classification-lookup',$currentId)/c:description\" /></category></xsl:for-each></xsl:template> <xsl:template match=\"text()\" />" +
    "<c:classifications><c:classification><c:id>3</c:id><c:description>Abortion Alternatives</c:description></c:classification><c:classification><c:id>4</c:id><c:description>Abortion Providers</c:description>" +
    "</c:classification><c:classification><c:id>9</c:id><c:description>Abrasives</c:description></c:classification></c:classifications></xsl:stylesheet>";

    Transformer transformer = xformFactory.newTransformer(new StreamSource(IOUtils.toInputStream(xsltString)));
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");

    FileOutputStream fileOutputStream = new FileOutputStream(new File(outputXmlFileName));  
    DOMSource source = new DOMSource(document);
    Result result = new StreamResult(fileOutputStream);
    transformer.transform(source, result);

    fileOutputStream.close();

}

когда я пытаюсь сделать это следующим образом (после написания modifiel xsl и чтения его обратно)

    Transformer transformer = xformFactory.newTransformer(new StreamSource(xsltFile));

работает нормально - но

    Transformer transformer = xformFactory.newTransformer(new StreamSource(IOUtils.toInputStream(xsltString))); does not process the lookup.

Ввод, как показано ниже

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BusinessListings vendorId="0" schemaVersion=""
fileCreateDate="" xmlns="http://www.myDomain.com">
<BusinessListing>
    <id>1593469</id>
    <listingData>
        <classifications>
            <classificationId>3</classificationId>
            <classificationId>9</classificationId>
        </classifications>
    </listingData>
</BusinessListing>
</BusinessListings>

в чем может быть проблема?

Ответы [ 2 ]

0 голосов
/ 15 июня 2011

Во-первых, чтобы ответить на ваш вопрос - обратитесь к спецификации XSLT 1.0, которая объясняет использование строкового аргумента нулевой длины для функции документа :

Обратите внимание, что ноль- ссылка на URI длины - это ссылка на документ, относительно которого разрешается ссылка на URI;таким образом, документ ("") относится к корневому узлу таблицы стилей;древовидное представление таблицы стилей точно такое же, как если бы XML-документ, содержащий таблицу стилей, был исходным исходным документом.

Поскольку источником вашей таблицы стилей является поток в памяти, URI отсутствуетиз которого решить это.Он работает с файлом, так как он может определить местоположение файла и перезагрузить его.Может быть какой-то способ заставить это работать с системным идентификатором или пользовательским распознавателем URI, но я думаю, что, вероятно, есть более простой подход.

Во-вторых, почему вы встраиваете данные классификации в XSLT?Почему бы просто не передать его в качестве параметра?Это кажется намного проще и будет работать в основном так же, заменив вызов документа ('') ссылкой на параметр.

0 голосов
/ 15 июня 2011

Можете ли вы передать ByteArrayInputStream в объект StreamSource?Вы можете инициализировать это строкой.

Что-то вроде:

ByteArrayInputStream bais = new ByteArrayInputStream(xsltString.getBytes(), "UTF-8");
Transformer transformer = xformFactory.newTransformer( new StreamSource( bais ) );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...