0

属性の最小値と最大値を取得し、それらをアクセス可能な変数に保存するための「より良い」ソリューションを見つけたいと思います。for-each-loop からも離れたいと思います。そんなことがあるものか?

私のXML:

<Rows>
  <Entry value1="16,423" value2="18,123" />
  <Entry value1="423" value2="11,588" />
  <Entry value1="1,168" value2="521" />
</Rows>

そして私のXSL:

<xsl:for-each select="Rows/Entry/@value1|Rows/Entry/@value2">
  <xsl:sort select="." data-type="number" />
  <xsl:choose>
    <xsl:when test="position() = 1">
      <xsl:variable name="min" select="format-number(translate(.,',',''),'#')" />
    </xsl:when>
    <xsl:when test="position() = last()">
      <xsl:variable name="max" select="format-number(translate(.,',',''),'#')" />
    </xsl:when>
  </xsl:choose>
</xsl:for-each>

望ましい出力は、数値として $min=423 および $max=18123 であり、for-each-loop の外でアクセスできる必要があります。

4

2 に答える 2

2

Well there is XSLT 2.0 since 2007 (implemented by XSLT processors like Saxon 9, AltovaXML, XmlPrime) where you can simply do (assuming you have the declaration xmlns:xs="http://www.w3.org/2001/XMLSchema" on your xsl:stylesheet element):

<xsl:variable name="min" select="min(Rows/Entry/(@value1, @value2)/xs:decimal(translate(., ',', ''))"/>
<xsl:variable name="max" select="max(Rows/Entry/(@value1, @value2)/xs:decimal(translate(., ',', ''))"/>

If you really want to store a formatted string in a variable you can of course do that as well with e.g.

<xsl:variable name="min" select="format-number(min(Rows/Entry/(@value1, @value2)/xs:decimal(translate(., ',', '')), '#')"/>
<xsl:variable name="max" select="format-number(max(Rows/Entry/(@value1, @value2)/xs:decimal(translate(., ',', '')), '#')"/>

As for XSLT 1.0, there I think the sorting with for-each is the right approach but you would need to pull the xsl:variable outside the for-each e.g.

<xsl:variable name="min">
 <xsl:for-each select="Rows/Entry/@value1|Rows/Entry/@value2">
  <xsl:sort select="translate(., ',', '')" data-type="number"/>
  <xsl:if test="position() = 1">
    <xsl:value-of select="format-number(., '#')"/>
  </xsl:if>
 </xsl:for-each>
</xsl:variable>

<xsl:variable name="max">
  <xsl:for-each select="Rows/Entry/@value1|Rows/Entry/@value2">
   <xsl:sort select="translate(., ',', '')" data-type="number"/>
   <xsl:if test="position() = last()">
      <xsl:value-of select="format-number(.,'#')" />
   </xsl:if>
  </xsl:for-each>
</xsl:variable>

As an alternative you could replace the for-each with apply-templates and then write a template matching @value1 | @value2 but while I think most tasks to transform nodes are better done using push style in XSLT I think for finding a minimum or maximum value the for-each is fine.

于 2013-06-27T09:40:12.867 に答える
1

絶対に正しいかどうかはわかりませんが、これを試してみました

(/Rows/Entry/@value1|/Rows/Entry/@value2)[not((/Rows/Entry/@value1|/Rows/Entry/@value2) &lt; .)]

そしてこれは最大

(/Rows/Entry/@value1|/Rows/Entry/@value2)[not((/Rows/Entry/@value1|/Rows/Entry/@value2) &gt; .)]

そしてそれはあなたが言及した価値を私に与えました。しかし、単純化するために、「、」のない値を持つ xml を使用しました。

于 2013-06-27T09:27:35.000 に答える