2016-02-13 1 views
0

Мой лист xsl преобразует обычный текст в svg. Я получаю простой текст от ввода пользователя на свой сервлет, и после этого я хочу, чтобы передавал вход в качестве параметра в мой лист xsl. Мой последний вопрос состоял в том, как передать параметр, и здесь отвечает (Pass user input to XSL stylesheet), но я понял, что не знаю, как вызвать преобразование. Мой xsl не принимает xml-вход, поэтому я не могу использовать transformer.transform, например. Как возможно, выполнить преобразование с параметром и получить результат в виде строки, которую я могу вернуть пользователю?Как выполнить преобразование xsl без ввода xml из java

Любая помощь будет оценена по достоинству. Если вам нужна дополнительная информация, дайте мне знать. Благодаря!

Edit: Если вы заинтересованы, идея заключается в том, что я могу превратить простую текстовую запись в SVG, и она работает, что первая часть преобразования преобразует обычный текст в XML-нотацию, и после этого XML в svg (XSLT 2.0: Transform notation in plain text to svg). Он отлично работает для простых символов, когда обычный текст находится в переменной. Но я хочу расширить веб-сервис с функциональностью, и должно быть возможно, что пользователь вводит ввод, поэтому я хочу передать параметр в свой xsl. Проблема в том, что я не знаю, как назвать преобразование из java, чтобы получить результат, чтобы вернуть его пользователю.

Здесь XSL:

<?xml version="1.0" encoding="UTF-8"?> 
<!-- Ansatz mit Hilfe von 
https://stackoverflow.com/questions/34682331/xslt-2-0-transform-notation-in-plain-text-to-svg --> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:local="local" 
    exclude-result-prefixes="xs" 
    version="2.0" 
    xmlns:svg="http://www.w3.org/2000/svg"> 
    <xsl:output indent="yes"/> 
<!-- 
<xsl:variable name="drawing-text"> 
GRAPHREP 
PEN color:$000000 w:2pt 
FILL color:$ff7f00 
ROUNDRECT x:0pt y:0pt w:114pt h:70pt rx:20pt ry:20pt 

</xsl:variable> 
--> 
<xsl:param name="drawing-text" /> 

    <!--matches sequences of UPPER-CASE letters --> 
    <xsl:variable name="label-pattern" select="'[A-Z]+'"/> 
    <!--matches the "attributes" in the line i.e. w:2pt, 
     has two capture groups (1) => attribute name, (2) => attribute value --> 
    <xsl:variable name="attribute-pattern" select="'\s?(\S+):(\S+)'"/> 
    <!--matches a line of data for the drawing text, 
     has two capture groups (1) => label, (2) attribute data--> 
    <xsl:variable name="line-pattern" select="concat('(', $label-pattern, ')\s(.*)\n?')"/> 
    <!-- Text in quotes holen--> 
    <xsl:variable name="text-pattern" select="'&quot;(.*?)&quot;'"/> 

    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/"> 
     <svg width="640" height="480"> 
      <g> 
       <!-- Find the text patterns indicating the shape --> 
       <!--Replaced unparsed-text() with local variable for testing     
       select="unparsed-text('drawing.txt')" --> 
       <xsl:analyze-string select="$drawing-text" 
        regex="{concat('(', $label-pattern, ')\n((', $line-pattern, ')+)\n?')}"> 
        <xsl:matching-substring> 
         <!--Convert text to XML --> 
         <xsl:variable name="drawing-markup" as="element()"> 
          <!--Create an element for this group, using first matched pattern as the element name 
           (i.e. GRAPHREP => <GRAPHREP>) --> 
          <xsl:element name="{regex-group(1)}"> 
           <!--split the second matched group for this shape into lines by breaking on newline--> 
           <xsl:variable name="lines" select="tokenize(regex-group(2), '\n')"/> 
           <xsl:for-each select="$lines"> 
            <!--for each line, run through this process to create an element with attributes 
             (e.g. FILL color:$frf7f00 => <FILL color=""/> 
            --> 
            <xsl:analyze-string select="." regex="{$line-pattern}"> 
             <xsl:matching-substring> 
              <!--create an element using the UPPER-CASE label starting the line --> 
              <xsl:element name="{regex-group(1)}"> 
               <!-- capture each of the attributes --> 
               <xsl:analyze-string select="regex-group(2)" regex="\s?(\S+):(\S+)"> 
                <xsl:matching-substring> 
                <!--convert foo:bar into attribute foo="bar", 
                  translate $ => # 
                  and remove the letters 'p' and 't' by translating into nothing"--> 
                <xsl:attribute name="{regex-group(1)}" select="translate(regex-group(2), '$pt', '#')"/> 
                </xsl:matching-substring> 
                <xsl:non-matching-substring/> 
               </xsl:analyze-string> 
              </xsl:element> 
             </xsl:matching-substring> 
             <xsl:non-matching-substring/> 
            </xsl:analyze-string> 
           </xsl:for-each> 
          </xsl:element> 
         </xsl:variable> 
         <!--Uncomment the copy-of below if you want to see the intermediate XML $drawing-markup--> 
         <!--<xsl:copy-of select="$drawing-markup"/>--> 

         <!-- Transform XML into SVG --> 
         <xsl:apply-templates select="$drawing-markup"/> 

        </xsl:matching-substring> 
        <xsl:non-matching-substring/> 
       </xsl:analyze-string> 
      </g> 
     </svg> 
    </xsl:template> 

    <!--==========================================--> 
    <!-- Templates to convert the $drawing-markup --> 
    <!--==========================================--> 

    <!--for supported shapes, create the element using 
     lower-case value, and change rectangle to rect 
     for the svg element name !!! if abfrage ob text--> 
    <xsl:template match="GRAPHREP[ELLIPSE | RECTANGLE | ROUNDRECT | LINE | TEXT]"> 
     <xsl:if test="ELLIPSE | RECTANGLE | ROUNDRECT | LINE"> 
      <xsl:element name="{replace(lower-case(local-name(ELLIPSE | RECTANGLE | ROUNDRECT | LINE)), 'rectangle|roundrect', 'rect', 'i')}"> 
       <xsl:attribute name="id" select="concat('id_', generate-id())"/> 
       <xsl:apply-templates /> 
      </xsl:element> 
     </xsl:if> 
     <xsl:if test="TEXT"> 
      <xsl:element name="{lower-case(local-name(TEXT))}"> 
       <xsl:attribute name="id" select="concat('id_', generate-id())"/> 
       <xsl:apply-templates /> 
       <!-- Da muss der text aus den quotes rein --> 
      </xsl:element> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="ELLIPSE | RECTANGLE | ROUNDRECT | LINE | TEXT"/> 

    <!-- Just process the content of GRAPHREP. 
     If there are multiple shapes and you want a new 
     <svg><g></g></svg> for each shape, 
     then move it from the template for "/" into this template--> 
    <xsl:template match="GRAPHREP/*"> 
     <xsl:apply-templates select="@*"/> 
    </xsl:template> 

    <xsl:template match="PEN" priority="1"> 
     <!--TODO: test if these attributes exist, if they do, do not create these defaults. 
      Hard-coding for now, to match desired output, since I don't know what the text 
      attributes would be, but could wrap each with <xsl:if test="not(@dasharray)">--> 
     <xsl:attribute name="stroke-dasharray" select="'null'"/> 
     <xsl:attribute name="stroke-linjoin" select="'null'"/> 
     <xsl:attribute name="stroke-linecap" select="'null'"/> 
     <xsl:apply-templates select="@*"/> 
    </xsl:template> 

    <!-- conterts @color => @stroke --> 
    <xsl:template match="PEN/@color"> 
     <xsl:attribute name="stroke" select="."/> 
    </xsl:template> 

    <!--converts @w => @stroke-width --> 
    <xsl:template match="PEN/@w"> 
     <xsl:attribute name="stroke-width" select="."/> 
    </xsl:template> 

    <!--converts @color => @fill and replaces $ with # --> 
    <xsl:template match="FILL/@color"> 
     <xsl:attribute name="fill" select="translate(., '$', '#')"/> 
    </xsl:template> 

    <!--converts @h => @font-size !!noch mit text verbinden --> 
    <xsl:template match="FONT/@h"> 
     <xsl:attribute name="font-size" select="."/> 
    </xsl:template> 

    <!--converts @color => @fill !!noch mit text verbinden --> 
    <xsl:template match="FONT/@color"> 
     <xsl:attribute name="fill" select="translate(., '$', '#')"/> 
    </xsl:template> 

    <!-- converts @x => @cx with hard-coded values. 
     May want to use value from text, but matching your example--> 
    <xsl:template match="ELLIPSE/@x | ELLIPSE/@y"> 
     <!--not sure if there was a relationship between ELLIPSE x:0pt y:0pt, and why 0pt would be 250, 
      but just an example...--> 
     <xsl:attribute name="c{name()}" select="250"/> 
    </xsl:template> 

    <xsl:template match="RECTANGLE/@w | ROUNDRECT/@w"> 
     <xsl:attribute name="{name()}idth" select="."/> 
    </xsl:template> 

    <xsl:template match="RECTANGLE/@h | ROUNDRECT/@h"> 
     <xsl:attribute name="{name()}eight" select="."/> 
    </xsl:template> 

    <xsl:template match="LINE/@x | LINE/@y"> 
     <xsl:attribute name="{name()}" select="."/> 
    </xsl:template> 

    <xsl:template match="TEXT/@x | TEXT/@y"> 
     <xsl:attribute name="{name()}" select="."/> 
    </xsl:template> 

</xsl:stylesheet> 
+0

У вас нет '' xsl: template match = "..."> 'в вашем XSLT? Это язык преобразования XML и * требует * ввода XML. Мне любопытно увидеть ваш XSLT! – Kenney

+0

Вы можете запустить преобразование в пустой экземпляр XML-документа, если ваш вывод XSLT не управляется XML, но фактически, например, '' или вызывает 'document()'. – Tomalak

+0

Если все данные, необходимые для получения результата, находятся в переданном параметре, почему бы вам не использовать фиктивный XML-документ в качестве входных данных? Это может быть что угодно, например. файл, содержащий только «». –

ответ

1

В XSLT 2.0 вы можете использовать именованный шаблон (например, путем изменения <xsl:template match="/"> к <xsl:template match="/" name="main">), а затем, например, с Saxon 9.6 вы можете использовать метод http://saxonica.com/html/documentation9.6/javadoc/net/sf/saxon/s9api/XsltTransformer.html#setInitialTemplate%28net.sf.saxon.s9api.QName%29 для установки myTransformer.setInitialTemplate(new QName("main")). См. http://saxonica.com/html/documentation9.6/using-xsl/embedding/s9api-transformation.html о том, как использовать его API.

API Java JAXP ориентирован на XSLT 1.0 и не позволяет запускать преобразование без входного документа, там вам действительно нужно предоставить фиктивный документ.

+0

спасибо. Я посмотрю! –

1

Там нет XSL-преобразование без ввода данных XML (в XSLT 1.0). Как отметил MartinHonnen, это возможно в XSLT2.0. (XSLT1.0 по-прежнему широко используется, поскольку 2.0 не поддерживается изначально в веб-браузерах)

Как сказал Томалак и Майкл, вы можете использовать пустой XML-документ в качестве входных данных для преобразования, а затем передать параметр.

Возможно, было бы лучше создать XML-документ с вашими входными данными в качестве содержимого, например. <dummy><input1>data from request</input1></dummy>

В XSL документе вы бы затем создать новый документ, например, так

<xsl:template match="/dummy"> 
This was the input: <xsl:value-of select="input1"/> 
</xsl:template> 

Примечания это только один пример, есть много способов для достижения этой цели.

И, наконец,, если вы хотите, чтобы ваш XSL для создания XML-документа с вашим вводом, возможно, вам следует изучить создание документа напрямую, не используя XSL.

Checkout этот учебник о том, как создать документ с нуля: http://examples.javacodegeeks.com/core-java/xml/dom/create-dom-document-from-scratch/

+1

XSLT 2.0 позволяет запускать таблицу стилей, начиная с именованного шаблона, в этом случае вам не нужен входной документ. –

+0

@MartinHonnen хорошо знать +1. Относительно этого вопроса, хотя для XSL (если нет существующего листа, который должен использоваться), громоздко использовать XSL. – robert

+0

Я предполагаю, что решение в http://stackoverflow.com/questions/34682331/xslt-2-0-transform-notation-in-plain-text-to-svg - это существующая таблица стилей, которая будет использоваться. –

Смежные вопросы