XSLT 按特定标签分组
XSLT grouping by specific tag
我有这个 XML 文档:
<?xml version="1.0" encoding="utf-8"?>
<Document>
<InvoiceLines>
<Lines>
<LineNume>1</LineNume>
<Description>Test1</Description>
<Quantity>200</Quantity>
<UnitPrice>500</UnitPrice>
<Amounts>
<Net>100000</Net>
<VATRate>
<Percent>2</Percent>
</VATRate>
<VATAmount>2000</VATAmount>
<Gross>102000</Gross>
</Amounts>
</Lines>
<Lines>
<LineNume>2</LineNume>
<Description>Test2</Description>
<Quantity>300</Quantity>
<UnitPrice>1000</UnitPrice>
<Amounts>
<Net>300000</Net>
<VATRate>
<Percent>3</Percent>
</VATRate>
<VATAmount>9000</VATAmount>
<Gross>309000</Gross>
</Amounts>
</Lines>
<Lines>
<LineNume>3</LineNume>
<Description>Test3</Description>
<Quantity>100</Quantity>
<UnitPrice>500</UnitPrice>
<Amounts>
<Net>50000</Net>
<VATRate>
<Percent>3</Percent>
</VATRate>
<VATAmount>1500</VATAmount>
<Gross>51500</Gross>
</Amounts>
</Lines>
<Lines>
<LineNume>4</LineNume>
<Description>Test4</Description>
<Quantity>100</Quantity>
<UnitPrice>500</UnitPrice>
<Amounts>
<Net>50000</Net>
<VATRate>
<Excempt>0</Excempt>
</VATRate>
<VATAmount>0</VATAmount>
<Gross>50000</Gross>
</Amounts>
</Lines>
</InvoiceLines>
</Document>
并使用此 XSLT 1.0 代码(更新):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:key name ="kVAT" match="Amounts" use ="concat(generate-id(..), VATRate/Percent | VATRate/Excempt)" />
<xsl:template match="Document/InvoiceLines">
<xsl:variable name="NetAmount" select="Lines/Amounts/Net" />
<xsl:variable name="VATAmount" select="Lines/Amounts/VATAmount" />
<xsl:variable name="GrossAmount" select="Lines/Amounts/Gross" />
<Summary>
<xsl:for-each select=
"//Amounts[generate-id() =
generate-id(
key('kVAT',
concat(generate-id(..), VATRate/Percent | VATRate/Excempt)
)[1]
)
]">
<xsl:variable name="keyGroup" select ="key('kVAT', concat(generate-id(..), VATRate/Percent | VATRate/Excempt))" />
<Rate>
<VATRate>
<xsl:choose>
<xsl:when test="$keyGroup/VATRate/Percent">
<Percent>
<xsl:value-of select ="$keyGroup/VATRate/Percent"/>
</Percent>
</xsl:when>
<xsl:otherwise>
<Excempt>
<xsl:value-of select ="$keyGroup/VATRate/Excempt"/>
</Excempt>
</xsl:otherwise>
</xsl:choose>
</VATRate>
<Net>
<xsl:value-of select ="$keyGroup/Net" />
</Net>
<VATAmount>
<xsl:value-of select ="$keyGroup/VATAmount" />
</VATAmount>
<Gross>
<xsl:value-of select ="$keyGroup/Gross" />
</Gross>
</Rate>
</xsl:for-each>
<NetAmount>
<xsl:value-of select ="sum($NetAmount)"/>
</NetAmount>
<VATAmount>
<xsl:value-of select ="sum($VATAmount)"/>
</VATAmount>
</Summary>
<GrossAmount>
<xsl:value-of select ="sum($GrossAmount)"/>
</GrossAmount>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有这个结果(更新):
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Summary>
<Rate>
<VATRate>
<Percent>2</Percent>
</VATRate>
<Net>100000</Net>
<VATAmount>2000</VATAmount>
<Gross>102000</Gross>
</Rate>
<Rate>
<VATRate>
<Percent>3</Percent>
</VATRate>
<Net>300000</Net>
<VATAmount>9000</VATAmount>
<Gross>309000</Gross>
</Rate>
<Rate>
<VATRate>
<Percent>3</Percent>
</VATRate>
<Net>50000</Net>
<VATAmount>1500</VATAmount>
<Gross>51500</Gross>
</Rate>
<Rate>
<VATRate>
<Excempt>0</Excempt>
</VATRate>
<Net>50000</Net>
<VATAmount>0</VATAmount>
<Gross>50000</Gross>
</Rate>
<NetAmount>500000</NetAmount>
<VATAmount>12500</VATAmount>
</Summary>
<GrossAmount>512500</GrossAmount>
</Document>
但我需要根据增值税税率分组,结果如下:
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Summary>
<Rate>
<Net>100000</Net>
<VATRate>
<Percent>2</Percent>
</VATRate>
<VATAmount>2000</VATAmount>
<Gross>102000</Gross>
</Rate>
<Rate>
<Net>350000</Net>
<VATRate>
<Percent>3</Percent>
</VATRate>
<VATAmount>10500</VATAmount>
<Gross>360500</Gross>
</Rate>
<Rate>
<Net>50000</Net>
<VATRate>
<Excempt>0</Excempt>
</VATRate>
<VATAmount>0</VATAmount>
<Gross>50000</Gross>
</Rate>
<NetAmount>500000</NetAmount>
<VATAmount>12500</VATAmount>
</Summary>
<GrossAmount>512500</GrossAmount>
</Document>
请注意 <Rate/VATRate>
标签可以包含 <percent>
或 <Excempt>
等的子标签。
我花了几天时间通过查找类似的主题来解决这个问题,但似乎可以找到。
任何人都可以帮助我解决我使用 XSLT 1.0 的这个问题,因为我们无法访问其他版本。
谢谢
怎么样:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="amt-by-rate" match="Amounts" use="VATRate/*" />
<xsl:template match="/Document">
<xsl:variable name="amounts" select="InvoiceLines/Lines/Amounts" />
<xsl:copy>
<Summary>
<xsl:for-each select="$amounts[count(. | key('amt-by-rate', VATRate/*)[1]) = 1]">
<xsl:variable name="current-group" select="key('amt-by-rate', VATRate/*)" />
<Rate>
<Net>
<xsl:value-of select="sum($current-group/Net)"/>
</Net>
<xsl:copy-of select="VATRate"/>
<VATAmount>
<xsl:value-of select="sum($current-group/VATAmount)"/>
</VATAmount>
<Gross>
<xsl:value-of select="sum($current-group/Gross)"/>
</Gross>
</Rate>
</xsl:for-each>
</Summary>
<NetAmount>
<xsl:value-of select="sum($amounts/Net)"/>
</NetAmount>
<VATAmount>
<xsl:value-of select="sum($amounts/VATAmount)"/>
</VATAmount>
<GrossAmount>
<xsl:value-of select="sum($amounts/Gross)"/>
</GrossAmount>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有这个 XML 文档:
<?xml version="1.0" encoding="utf-8"?>
<Document>
<InvoiceLines>
<Lines>
<LineNume>1</LineNume>
<Description>Test1</Description>
<Quantity>200</Quantity>
<UnitPrice>500</UnitPrice>
<Amounts>
<Net>100000</Net>
<VATRate>
<Percent>2</Percent>
</VATRate>
<VATAmount>2000</VATAmount>
<Gross>102000</Gross>
</Amounts>
</Lines>
<Lines>
<LineNume>2</LineNume>
<Description>Test2</Description>
<Quantity>300</Quantity>
<UnitPrice>1000</UnitPrice>
<Amounts>
<Net>300000</Net>
<VATRate>
<Percent>3</Percent>
</VATRate>
<VATAmount>9000</VATAmount>
<Gross>309000</Gross>
</Amounts>
</Lines>
<Lines>
<LineNume>3</LineNume>
<Description>Test3</Description>
<Quantity>100</Quantity>
<UnitPrice>500</UnitPrice>
<Amounts>
<Net>50000</Net>
<VATRate>
<Percent>3</Percent>
</VATRate>
<VATAmount>1500</VATAmount>
<Gross>51500</Gross>
</Amounts>
</Lines>
<Lines>
<LineNume>4</LineNume>
<Description>Test4</Description>
<Quantity>100</Quantity>
<UnitPrice>500</UnitPrice>
<Amounts>
<Net>50000</Net>
<VATRate>
<Excempt>0</Excempt>
</VATRate>
<VATAmount>0</VATAmount>
<Gross>50000</Gross>
</Amounts>
</Lines>
</InvoiceLines>
</Document>
并使用此 XSLT 1.0 代码(更新):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:key name ="kVAT" match="Amounts" use ="concat(generate-id(..), VATRate/Percent | VATRate/Excempt)" />
<xsl:template match="Document/InvoiceLines">
<xsl:variable name="NetAmount" select="Lines/Amounts/Net" />
<xsl:variable name="VATAmount" select="Lines/Amounts/VATAmount" />
<xsl:variable name="GrossAmount" select="Lines/Amounts/Gross" />
<Summary>
<xsl:for-each select=
"//Amounts[generate-id() =
generate-id(
key('kVAT',
concat(generate-id(..), VATRate/Percent | VATRate/Excempt)
)[1]
)
]">
<xsl:variable name="keyGroup" select ="key('kVAT', concat(generate-id(..), VATRate/Percent | VATRate/Excempt))" />
<Rate>
<VATRate>
<xsl:choose>
<xsl:when test="$keyGroup/VATRate/Percent">
<Percent>
<xsl:value-of select ="$keyGroup/VATRate/Percent"/>
</Percent>
</xsl:when>
<xsl:otherwise>
<Excempt>
<xsl:value-of select ="$keyGroup/VATRate/Excempt"/>
</Excempt>
</xsl:otherwise>
</xsl:choose>
</VATRate>
<Net>
<xsl:value-of select ="$keyGroup/Net" />
</Net>
<VATAmount>
<xsl:value-of select ="$keyGroup/VATAmount" />
</VATAmount>
<Gross>
<xsl:value-of select ="$keyGroup/Gross" />
</Gross>
</Rate>
</xsl:for-each>
<NetAmount>
<xsl:value-of select ="sum($NetAmount)"/>
</NetAmount>
<VATAmount>
<xsl:value-of select ="sum($VATAmount)"/>
</VATAmount>
</Summary>
<GrossAmount>
<xsl:value-of select ="sum($GrossAmount)"/>
</GrossAmount>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有这个结果(更新):
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Summary>
<Rate>
<VATRate>
<Percent>2</Percent>
</VATRate>
<Net>100000</Net>
<VATAmount>2000</VATAmount>
<Gross>102000</Gross>
</Rate>
<Rate>
<VATRate>
<Percent>3</Percent>
</VATRate>
<Net>300000</Net>
<VATAmount>9000</VATAmount>
<Gross>309000</Gross>
</Rate>
<Rate>
<VATRate>
<Percent>3</Percent>
</VATRate>
<Net>50000</Net>
<VATAmount>1500</VATAmount>
<Gross>51500</Gross>
</Rate>
<Rate>
<VATRate>
<Excempt>0</Excempt>
</VATRate>
<Net>50000</Net>
<VATAmount>0</VATAmount>
<Gross>50000</Gross>
</Rate>
<NetAmount>500000</NetAmount>
<VATAmount>12500</VATAmount>
</Summary>
<GrossAmount>512500</GrossAmount>
</Document>
但我需要根据增值税税率分组,结果如下:
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Summary>
<Rate>
<Net>100000</Net>
<VATRate>
<Percent>2</Percent>
</VATRate>
<VATAmount>2000</VATAmount>
<Gross>102000</Gross>
</Rate>
<Rate>
<Net>350000</Net>
<VATRate>
<Percent>3</Percent>
</VATRate>
<VATAmount>10500</VATAmount>
<Gross>360500</Gross>
</Rate>
<Rate>
<Net>50000</Net>
<VATRate>
<Excempt>0</Excempt>
</VATRate>
<VATAmount>0</VATAmount>
<Gross>50000</Gross>
</Rate>
<NetAmount>500000</NetAmount>
<VATAmount>12500</VATAmount>
</Summary>
<GrossAmount>512500</GrossAmount>
</Document>
请注意 <Rate/VATRate>
标签可以包含 <percent>
或 <Excempt>
等的子标签。
我花了几天时间通过查找类似的主题来解决这个问题,但似乎可以找到。
任何人都可以帮助我解决我使用 XSLT 1.0 的这个问题,因为我们无法访问其他版本。
谢谢
怎么样:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="amt-by-rate" match="Amounts" use="VATRate/*" />
<xsl:template match="/Document">
<xsl:variable name="amounts" select="InvoiceLines/Lines/Amounts" />
<xsl:copy>
<Summary>
<xsl:for-each select="$amounts[count(. | key('amt-by-rate', VATRate/*)[1]) = 1]">
<xsl:variable name="current-group" select="key('amt-by-rate', VATRate/*)" />
<Rate>
<Net>
<xsl:value-of select="sum($current-group/Net)"/>
</Net>
<xsl:copy-of select="VATRate"/>
<VATAmount>
<xsl:value-of select="sum($current-group/VATAmount)"/>
</VATAmount>
<Gross>
<xsl:value-of select="sum($current-group/Gross)"/>
</Gross>
</Rate>
</xsl:for-each>
</Summary>
<NetAmount>
<xsl:value-of select="sum($amounts/Net)"/>
</NetAmount>
<VATAmount>
<xsl:value-of select="sum($amounts/VATAmount)"/>
</VATAmount>
<GrossAmount>
<xsl:value-of select="sum($amounts/Gross)"/>
</GrossAmount>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>