как сделатьна прилавке изначение по умолчанию - PullRequest
1 голос
/ 18 ноября 2011

Этот пост является расширением XSLT, преобразующим xml .

В этом результирующем xml, полученном в вышеупомянутом посте, я хочу иметь такие функции, как строки и начало.

Например) Если как часть ввода я даю

<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">1</int>
    <lst name="params">
      <str name="indent">on</str>
      <str name="q">"what"</str>
      <str name="rows">2</str>
      <str name="start">1</str>
    </lst>
  </lst>
  <result name="response" numFound="1" start="0">
    <doc>
      <str name="query">what</str>
      <arr name="suggestion">
        <str>what1</str>
        <str>what2</str>
        <str>what3</str>
        <str>what4</str>
        <str>what5</str>
      </arr>
    </doc>
  </result>
</response>

, используя упомянутый xsl в предыдущем посте, упомянутом выше, я могу получить вывод,

<response>
    <lst name="responseHeader">
        <int name="status">0</int>
        <int name="QTime">1</int>
        <lst name="params">
            <str name="indent">on</str>
            <str name="q">"what"</str>
            <!--str name="rows">
        2</str>
        <str name="start">1</str-->
    </lst>
</lst>
<result name="response" numfound="5" start="0">
    <doc>
        <str name="query">what</str>
        <str name="suggestion">what1</str>
        <float name="score">100</float>
    </doc>
    <doc>
        <str name="query">what</str>
        <str name="suggestion">what2</str>
        <float name="score">200</float>
    </doc>
    <doc>
        <str name="query">what</str>
        <str name="suggestion">what3</str>
        <float name="score">300</float>
    </doc>
    <doc>
        <str name="query">what</str>
        <str name="suggestion">what4</str>
        <float name="score">400</float>
    </doc>
    <doc>
        <str name="query">what</str>
        <str name="suggestion">what5</str>
        <float name="score">500</float>
    </doc>
</result>
</response>

и когда я даю start = 2, я ожидаю, что предложения начнутся с what3 после пропуска 0 и 1-го предложения.

Также, когда я даю rows = 1, это означает, что я должен получить только один результат, начиная с "start "position

Также я хочу убедиться, что для строк и начала заданы значения по умолчанию.Следовательно, просматривая сеть, я мог найти этот пост: http://remysharp.com/2008/08/15/how-to-default-a-variable-in-xslt/

Есть ли лучший способ указать значение по умолчанию для переменной, например, использовать что-то вроде атрибута по умолчанию?Я пытался использовать атрибут по умолчанию.Но, похоже, это не используется.

Также я мог видеть <xsl:for-each>, перебирающий массив.Но я не знаю, как сделать так, чтобы у него были начальные и конечные значения, например, если начальное значение равно 2, а количество строк равно 2, тогда я хочу что-то вроде

<xsl:for-each select="counter" start="$start" end = "$end">
<doc>
 <str name="query">what</str>
 <str name="suggestion"><xsl:value-of select="//arr[@name='suggestion'][start]"</str>
</doc>
</xsl:for-each>

Любые предложения, пожалуйста ...

Мое решение:

Попробовал еще и, наконец, рад узнать немного о xsl :) Спасибо Dimitre и G_H (из предыдущего поста) ..

XSL создано:

<xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

    <xsl:template match="/response/result">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:attribute name="numFound"><xsl:value-of select="count(doc/arr[@name='suggestion']/str)" /></xsl:attribute>
            <xsl:apply-templates select="doc/arr[@name='suggestion']" />
        </xsl:copy>
    </xsl:template>



    <xsl:template match="arr[@name='suggestion']">
   <xsl:variable name="rows" as="xs:integer">
   <xsl:choose>
      <xsl:when test="/response/lst/lst/str[@name='rows']"><xsl:value-of select="/response/lst/lst/str[@name='rows']"/></xsl:when>
      <xsl:otherwise>10</xsl:otherwise> <!-- default value -->
   </xsl:choose>
</xsl:variable>
 <xsl:variable name="start" as="xs:integer">
   <xsl:choose>
      <xsl:when test="/response/lst/lst/str[@name='start']"><xsl:value-of select="/response/lst/lst/str[@name='rows']"/></xsl:when>
      <xsl:otherwise>0</xsl:otherwise> <!-- default value -->
   </xsl:choose>
</xsl:variable>

        <xsl:for-each select="str">          
          <xsl:if test="position()-1 &gt;= $start and position() &lt;= $rows+$start">
            <doc>
                <xsl:copy-of select="parent::node()/preceding-sibling:: str[@name='query']" />
                <xsl:variable name="nameAttributeValue" select="parent::node()/@name" />
                <xsl:element name="str"><xsl:attribute name="name"><xsl:value-of select="$nameAttributeValue" /></xsl:attribute><xsl:value-of select="." /></xsl:element>
                      <float name="score">
                           <xsl:value-of select="100*position()"/>
                      </float>

            </doc>

            </xsl:if>     
        </xsl:for-each>


    </xsl:template>

</xsl:stylesheet>

Ввод:

 <response>
      <lst name="responseHeader">
        <int name="status">0</int>
        <int name="QTime">1</int>
        <lst name="params">
          <str name="indent">on</str>
          <str name="q">"what"</str>
           <str name="rows">2</str>
          <str name="start">2</str>     
        </lst>
      </lst>
      <result name="response" numFound="1" start="0">
        <doc>
          <str name="query">what</str>
          <arr name="suggestion">
            <str>what1</str>
            <str>what2</str>
            <str>what3</str>
            <str>what4</str>
            <str>what5</str>
          </arr>
        </doc>
      </result>
    </response>

Выход

 <response>
        <lst name="responseHeader">
            <int name="status">0</int>
            <int name="QTime">1</int>
            <lst name="params">
                <str name="indent">on</str>
                <str name="q">"what"</str>
                <str name="rows">2</str>
                <str name="start">2</str>
            </lst>
        </lst>
        <result name="response" numfound="5" start="0">
            <doc>
                <str name="query">what</str>
                <str name="suggestion">what3</str>
                <float name="score">300</float>
            </doc>
            <doc>
                <str name="query">what</str>
                <str name="suggestion">what4</str>
                <float name="score">400</float>
            </doc>
        </result>
    </response>

Наконец, мне может понадобиться изменить параметр numfound в зависимости от заданного количества документов.Еще раз большое спасибо за ваше руководство:)

1 Ответ

1 голос
/ 18 ноября 2011

Вот преобразование XSLT 2.0, которое дает желаемый результат :

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 exclude-result-prefixes="xs">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pdefStart" as="xs:integer" select="1"/>
 <xsl:param name="pdefRows" as="xs:integer"  select="9999999"/>

 <xsl:variable name="vStart" as="xs:integer" select=
  "(/*/lst/lst/str[@name='start'],
    $pdefStart
    )
     [1]
  "/>

 <xsl:variable name="vRows" as="xs:integer" select=
  "(/*/lst/lst/str[@name='rows'],
    $pdefRows
    )
     [1]
  "/>

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

 <xsl:template match="result">
    <result numFound=
       "{count(doc/arr/str
              [position() ge $vStart
             and
              position() lt $vStart + $vRows
               ]
               )}"
         start="{$vStart}">
        <xsl:apply-templates/>
    </result>
 </xsl:template>

 <xsl:template match=
   "arr[@name='suggestion']/str
          [position() ge $vStart
         and
           position() lt $vStart + $vRows
          ]">
    <doc>
        <xsl:copy-of select="../../str"/>
        <xsl:copy-of select="."/>
        <float name="score">
         <xsl:value-of select="100*position()"/>
        </float>
    </doc>
 </xsl:template>
 <xsl:template match="doc|doc/arr">
    <xsl:apply-templates/>
 </xsl:template>
 <xsl:template match="str"/>

</xsl:stylesheet>

при применении к этому документу XML (на основе предоставленных, но с более «интересными» значениями для rows и start):

<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">1</int>
    <lst name="params">
      <str name="indent">on</str>
      <str name="q">"what"</str>
      <str name="rows">3</str>
      <str name="start">2</str>
    </lst>
  </lst>
  <result name="response" numFound="1" start="0">
    <doc>
      <str name="query">what</str>
      <arr name="suggestion">
        <str>what1</str>
        <str>what2</str>
        <str>what3</str>
        <str>what4</str>
        <str>what5</str>
      </arr>
    </doc>
  </result>
</response>

желаемый, правильный результат получается :

<response>
   <lst name="responseHeader">
      <int name="status">0</int>
      <int name="QTime">1</int>
      <lst name="params"/>
   </lst>
   <result numFound="3" start="2">
      <doc>
         <str name="query">what</str>
         <str>what2</str>
         <float name="score">200</float>
      </doc>
      <doc>
         <str name="query">what</str>
         <str>what3</str>
         <float name="score">300</float>
      </doc>
      <doc>
         <str name="query">what</str>
         <str>what4</str>
         <float name="score">400</float>
      </doc>
   </result>
</response>

Значения по умолчанию в преобразовании установлены таким образом, что , если в документе XML не указано start, мы предполагаем start = 1, а если rows не указано, мы предполагаем rows = 9999999 - то есть в случае по умолчанию мы хотим получить столько же элементов str, сколько в документе.

Вот пример :

<response>
  <lst name="responseHeader">
    <int name="status">0</int>
    <int name="QTime">1</int>
    <lst name="params">
      <str name="indent">on</str>
      <str name="q">"what"</str>
    </lst>
  </lst>
  <result name="response" numFound="1" start="0">
    <doc>
      <str name="query">what</str>
      <arr name="suggestion">
        <str>what1</str>
        <str>what2</str>
        <str>what3</str>
        <str>what4</str>
        <str>what5</str>
      </arr>
    </doc>
  </result>
</response>

Этот документ не имеет rows и start, и при обработке с вышеуказанным преобразованием используются значения по умолчанию, в результате которых получается :

<response>
   <lst name="responseHeader">
      <int name="status">0</int>
      <int name="QTime">1</int>
      <lst name="params"/>
   </lst>
   <result numFound="5" start="1">
      <doc>
         <str name="query">what</str>
         <str>what1</str>
         <float name="score">100</float>
      </doc>
      <doc>
         <str name="query">what</str>
         <str>what2</str>
         <float name="score">200</float>
      </doc>
      <doc>
         <str name="query">what</str>
         <str>what3</str>
         <float name="score">300</float>
      </doc>
      <doc>
         <str name="query">what</str>
         <str>what4</str>
         <float name="score">400</float>
      </doc>
      <doc>
         <str name="query">what</str>
         <str>what5</str>
         <float name="score">500</float>
      </doc>
   </result>
</response>

Наконец, обратите внимание : для максимальной гибкости значения по умолчанию указываются как глобальные параметры и могут быть переданы извне в преобразование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...