使用 XSLT 获取余数
Getting the Remainder using XSLT
我第一次写这篇文章是在 xslt 中(可以是 xslt 2 或 3)。我需要所有余数的总和。有人遇到过这个吗?谢谢。
这是要求:
2 IDs fields called id1 and id2. Each field has 6 chars (incl. space and decimal)
LEFT ALIGN:
id1: 111 (3 spaces included here after 111)
RIGHT ALIGN:
id2: 123.50 (one decimal here)
我需要获取第一个值 A、B、C、D 而:
VALUE A: add up id1 from position 1 - 3
VALUE B: add up id1 from position 4 - 6
VALUE C: add up id2 from position 1 - 3
VALUE D: add up id2 from position 4 - 6
注意:space 的值为 20,小数点为“.”是 15.
示例计算
id1: 111 (3 spaces included here)
VALUE A: 3 (1+1+1) AND
VALUE B: 60 (20+20+20)
id2: 123.50 (one decimal here)
VALUE C: 5 (1+2+3) AND
VALUE D: 20 (15+5)
Remainder= mod(abs((B+D)-(A+C)),13)
7
Sum of all remainders: 7
Example 2:
Row 1:
LEFT ALIGN:
id1: 111 (3 spaces included here after 111)
RIGHT ALIGN
id2: 123.50
Row 2:
LEFT ALIGN:
id1: 321.50
RIGHT ALIGN
id2: 222 (3 spaces before 111)
Row 1:
Value A: 3 (1+1+1)
Value B: 60 (20+20+20)
Value C: 6 (1+2+3)
Value D: 20 (15+5)
Row 2:
Value A: 6 (3+2+1)
Value B: 20 (15+5)
Value C:60 (20+20+20
Value D: 6 (2+2+2)
Remainder= mod(abs((B+D)-(A+C)),13)
Row1: Remainder = mod(abs((60+20)-(3+6)),13)
Remainder = 6
Row 2:Remainder=mod(abs((20+6)-(6+6)),13)
Remainder = 1
Sum of all remainders: 7 (6+1)
7 or the sum of all remainders will be included in the final output file.
感谢您的帮助。
对于 XSLT 3,一种方法可能是使用累加器:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="text" item-separator=" "/>
<xsl:mode on-no-match="shallow-skip" use-accumulators="#all"/>
<xsl:accumulator name="A" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data/id1"
phase="end"
select="accumulator-after('values') => subsequence(1, 3) => sum()"/>
</xsl:accumulator>
<xsl:accumulator name="B" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data/id1"
phase="end"
select="accumulator-after('values') => subsequence(4, 3) => sum()"/>
</xsl:accumulator>
<xsl:accumulator name="C" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data/id2"
phase="end"
select="accumulator-after('values') => subsequence(1, 3) => sum()"/>
</xsl:accumulator>
<xsl:accumulator name="D" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data/id2"
phase="end"
select="accumulator-after('values') => subsequence(4, 3) => sum()"/>
</xsl:accumulator>
<xsl:accumulator name="values" as="xs:integer*" initial-value="()">
<xsl:accumulator-rule
match="data" select="()"/>
<xsl:accumulator-rule
match="data/id1/text() | data/id2/text()"
select="analyze-string(.,'.')//*:match ! (
if (. = '.')
then 15
else if (. = ' ')
then 20
else xs:integer(.))"/>
</xsl:accumulator>
<xsl:accumulator name="remainder" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data" select="()"/>
<xsl:accumulator-rule
match="fields/data"
phase="end"
select="abs((accumulator-after('B') + accumulator-after('D')) -
(accumulator-after('A') + accumulator-after('C'))) mod 13"/>
</xsl:accumulator>
<xsl:accumulator name="remainder-sum" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields" select="0"/>
<xsl:accumulator-rule
match="fields/data"
select="$value + accumulator-after('remainder')"/>
</xsl:accumulator>
<xsl:output method="text" item-separator=" "/>
<xsl:template match="fields">
<xsl:apply-templates/>
<xsl:sequence
select="accumulator-after('remainder-sum')"/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bwe3bG/1
当然你只能将代码应用到最后一个元素
<xsl:template match="fields[last()]">
<xsl:apply-templates/>
<xsl:sequence
select="accumulator-after('remainder-sum')"/>
</xsl:template>
(而不是之前使用的 <xsl:template match="fields">
)。参见 https://xsltfiddle.liberty-development.net/bwe3bG/2
我第一次写这篇文章是在 xslt 中(可以是 xslt 2 或 3)。我需要所有余数的总和。有人遇到过这个吗?谢谢。
这是要求:
2 IDs fields called id1 and id2. Each field has 6 chars (incl. space and decimal)
LEFT ALIGN:
id1: 111 (3 spaces included here after 111)
RIGHT ALIGN:
id2: 123.50 (one decimal here)
我需要获取第一个值 A、B、C、D 而:
VALUE A: add up id1 from position 1 - 3
VALUE B: add up id1 from position 4 - 6
VALUE C: add up id2 from position 1 - 3
VALUE D: add up id2 from position 4 - 6
注意:space 的值为 20,小数点为“.”是 15.
示例计算
id1: 111 (3 spaces included here)
VALUE A: 3 (1+1+1) AND
VALUE B: 60 (20+20+20)
id2: 123.50 (one decimal here)
VALUE C: 5 (1+2+3) AND
VALUE D: 20 (15+5)
Remainder= mod(abs((B+D)-(A+C)),13)
7
Sum of all remainders: 7
Example 2:
Row 1:
LEFT ALIGN:
id1: 111 (3 spaces included here after 111)
RIGHT ALIGN
id2: 123.50
Row 2:
LEFT ALIGN:
id1: 321.50
RIGHT ALIGN
id2: 222 (3 spaces before 111)
Row 1:
Value A: 3 (1+1+1)
Value B: 60 (20+20+20)
Value C: 6 (1+2+3)
Value D: 20 (15+5)
Row 2:
Value A: 6 (3+2+1)
Value B: 20 (15+5)
Value C:60 (20+20+20
Value D: 6 (2+2+2)
Remainder= mod(abs((B+D)-(A+C)),13)
Row1: Remainder = mod(abs((60+20)-(3+6)),13)
Remainder = 6
Row 2:Remainder=mod(abs((20+6)-(6+6)),13)
Remainder = 1
Sum of all remainders: 7 (6+1)
7 or the sum of all remainders will be included in the final output file.
感谢您的帮助。
对于 XSLT 3,一种方法可能是使用累加器:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="text" item-separator=" "/>
<xsl:mode on-no-match="shallow-skip" use-accumulators="#all"/>
<xsl:accumulator name="A" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data/id1"
phase="end"
select="accumulator-after('values') => subsequence(1, 3) => sum()"/>
</xsl:accumulator>
<xsl:accumulator name="B" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data/id1"
phase="end"
select="accumulator-after('values') => subsequence(4, 3) => sum()"/>
</xsl:accumulator>
<xsl:accumulator name="C" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data/id2"
phase="end"
select="accumulator-after('values') => subsequence(1, 3) => sum()"/>
</xsl:accumulator>
<xsl:accumulator name="D" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data/id2"
phase="end"
select="accumulator-after('values') => subsequence(4, 3) => sum()"/>
</xsl:accumulator>
<xsl:accumulator name="values" as="xs:integer*" initial-value="()">
<xsl:accumulator-rule
match="data" select="()"/>
<xsl:accumulator-rule
match="data/id1/text() | data/id2/text()"
select="analyze-string(.,'.')//*:match ! (
if (. = '.')
then 15
else if (. = ' ')
then 20
else xs:integer(.))"/>
</xsl:accumulator>
<xsl:accumulator name="remainder" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields/data" select="()"/>
<xsl:accumulator-rule
match="fields/data"
phase="end"
select="abs((accumulator-after('B') + accumulator-after('D')) -
(accumulator-after('A') + accumulator-after('C'))) mod 13"/>
</xsl:accumulator>
<xsl:accumulator name="remainder-sum" as="xs:integer?" initial-value="()">
<xsl:accumulator-rule
match="fields" select="0"/>
<xsl:accumulator-rule
match="fields/data"
select="$value + accumulator-after('remainder')"/>
</xsl:accumulator>
<xsl:output method="text" item-separator=" "/>
<xsl:template match="fields">
<xsl:apply-templates/>
<xsl:sequence
select="accumulator-after('remainder-sum')"/>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bwe3bG/1
当然你只能将代码应用到最后一个元素
<xsl:template match="fields[last()]">
<xsl:apply-templates/>
<xsl:sequence
select="accumulator-after('remainder-sum')"/>
</xsl:template>
(而不是之前使用的 <xsl:template match="fields">
)。参见 https://xsltfiddle.liberty-development.net/bwe3bG/2