删除重复项,同时忽略空白值并在 XSLT 中添加 LineAmount
Remove duplicates while ignoring blank values and adding LineAmount in XSLT
我有一个要求,我需要删除重复的 SGSRollupItemName,同时忽略空白的 SGSRollupItemName 并添加重复的 SGSRollupItemName 的 LineAmount。我已经编写了删除重复的 SGSRollupItemName 的代码,虽然它正在删除重复的 SGSRollupItemName,但它也删除了不重复且具有空白值的 SGSRollupItemName。
下面是输入 xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Invoice>
<InvoiceLines>
<LineAmount>200.00</LineAmount>
<SGSRollupItemName>Test</SGSRollupItemName>
<SGSRollupItemNotes>PT</SGSRollupItemNotes>
</InvoiceLines>
<InvoiceLines>
<LineAmount>300.00</LineAmount>
<SGSRollupItemName>Test1</SGSRollupItemName>
<SGSRollupItemNotes>PT</SGSRollupItemNotes>
</InvoiceLines>
<InvoiceLines>
<LineAmount>250.00</LineAmount>
<SGSRollupItemName>Test</SGSRollupItemName>
<SGSRollupItemNotes>PT</SGSRollupItemNotes>
</InvoiceLines>
<InvoiceLines>
<LineAmount>400.00</LineAmount>
<SGSRollupItemName></SGSRollupItemName>
<SGSRollupItemNotes></SGSRollupItemNotes>
</InvoiceLines>
<InvoiceLines>
<LineAmount>500.00</LineAmount>
<SGSRollupItemName></SGSRollupItemName>
<SGSRollupItemNotes></SGSRollupItemNotes>
</InvoiceLines>
</Invoice>
</root>
这是我正在使用的 xslt 代码
<?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"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:key name="dups" match="InvoiceLines[normalize-space(SGSRollupItemName)]" use="concat(generate-id(..), '|', SGSRollupItemName)" />
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<cXML>
<Header/>
<Request xslt="XML">
<InvoiceDetailRequest>
<InvoiceDetailRequestHeader>
</InvoiceDetailRequestHeader>
<xsl:for-each select="Invoice/InvoiceLines[normalize-space(SGSRollupItemName)][not(generate-id() = generate-id(key('dups',concat(generate-id(..), '|', SGSRollupItemName))[1]))]">
<InvoiceDetailOrder>
<InvoiceDetailItem >
<xsl:variable name="numbers">
<xsl:for-each select="key('dups', concat(generate-id(..), '|',SGSRollupItemName ))/LineAmount">
<num>
<xsl:value-of select="translate(., ',', '')"/>
</num>
</xsl:for-each>
</xsl:variable>
<UnitPrice>
<Money>
<xsl:value-of select="format-number(sum(exsl:node-set($numbers)/num),'0.00,#')"/>
</Money>
</UnitPrice>
<NetAmount>
<Money>
<xsl:value-of select="format-number(sum(exsl:node-set($numbers)/num),'0.00,#')"/>
</Money>
</NetAmount>
<Comments>
<xsl:value-of select="./SGSRollupItemName/text()"/>
</Comments>
<Comments>
<xsl:value-of select ="./SGSRollupItemNotes/text()"/>
</Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
</xsl:for-each>
</InvoiceDetailRequest>
</Request>
</cXML>
</xsl:template>
</xsl:stylesheet>
下面是我得到的输出
<?xml version="1.0" encoding="utf-8"?>
<cXML>
<Header />
<Request xslt="XML">
<InvoiceDetailRequest>
<InvoiceDetailRequestHeader />
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>450.00</Money>
</UnitPrice>
<NetAmount>
<Money>450.00</Money>
</NetAmount>
<Comments>Test</Comments>
<Comments>PT</Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
</InvoiceDetailRequest>
</Request>
</cXML>
但下面是预期的输出
<?xml version="1.0" encoding="utf-8"?>
<cXML>
<Header />
<Request xslt="XML">
<InvoiceDetailRequest>
<InvoiceDetailRequestHeader />
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>450.00</Money>
</UnitPrice>
<NetAmount>
<Money>450.00</Money>
</NetAmount>
<Comments>Test</Comments>
<Comments>PT</Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>300.00</Money>
</UnitPrice>
<NetAmount>
<Money>300.00</Money>
</NetAmount>
<Comments>Test1</Comments>
<Comments>PT</Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>400.00</Money>
</UnitPrice>
<NetAmount>
<Money>400.00</Money>
</NetAmount>
<Comments></Comments>
<Comments></Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>500.00</Money>
</UnitPrice>
<NetAmount>
<Money>500.00</Money>
</NetAmount>
<Comments></Comments>
<Comments></Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
</InvoiceDetailRequest>
</Request>
</cXML>
能否请您指出我在 xslt 代码中做错了什么
问题不是很清楚。查看预期的输出,您似乎想要对 SGSRollupItemName
不为空的行进行分组,并分别列出空白的行。
如果是这样,请考虑以下简化示例:
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:key name="dups" match="InvoiceLines" use="concat(generate-id(..), '|', SGSRollupItemName)"/>
<xsl:template match="/root">
<cXML>
<!-- group non-blank items -->
<xsl:for-each select="Invoice/InvoiceLines[normalize-space(SGSRollupItemName)][generate-id() = generate-id(key('dups', concat(generate-id(..), '|', SGSRollupItemName))[1])]">
<InvoiceDetailOrder>
<Money>
<xsl:value-of select="format-number(sum(key('dups', concat(generate-id(..), '|',SGSRollupItemName ))/LineAmount),'0.00')"/>
</Money>
<Comments>
<xsl:value-of select="SGSRollupItemName"/>
</Comments>
</InvoiceDetailOrder>
</xsl:for-each>
<!-- list blank items -->
<xsl:for-each select="Invoice/InvoiceLines[not(normalize-space(SGSRollupItemName))]">
<InvoiceDetailOrder>
<Money>
<xsl:value-of select="LineAmount"/>
</Money>
<Comments>
<xsl:value-of select="SGSRollupItemName"/>
</Comments>
</InvoiceDetailOrder>
</xsl:for-each>
</cXML>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<cXML>
<InvoiceDetailOrder>
<Money>450.00</Money>
<Comments>Test</Comments>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<Money>300.00</Money>
<Comments>Test1</Comments>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<Money>400.00</Money>
<Comments/>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<Money>500.00</Money>
<Comments/>
</InvoiceDetailOrder>
</cXML>
我有一个要求,我需要删除重复的 SGSRollupItemName,同时忽略空白的 SGSRollupItemName 并添加重复的 SGSRollupItemName 的 LineAmount。我已经编写了删除重复的 SGSRollupItemName 的代码,虽然它正在删除重复的 SGSRollupItemName,但它也删除了不重复且具有空白值的 SGSRollupItemName。 下面是输入 xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Invoice>
<InvoiceLines>
<LineAmount>200.00</LineAmount>
<SGSRollupItemName>Test</SGSRollupItemName>
<SGSRollupItemNotes>PT</SGSRollupItemNotes>
</InvoiceLines>
<InvoiceLines>
<LineAmount>300.00</LineAmount>
<SGSRollupItemName>Test1</SGSRollupItemName>
<SGSRollupItemNotes>PT</SGSRollupItemNotes>
</InvoiceLines>
<InvoiceLines>
<LineAmount>250.00</LineAmount>
<SGSRollupItemName>Test</SGSRollupItemName>
<SGSRollupItemNotes>PT</SGSRollupItemNotes>
</InvoiceLines>
<InvoiceLines>
<LineAmount>400.00</LineAmount>
<SGSRollupItemName></SGSRollupItemName>
<SGSRollupItemNotes></SGSRollupItemNotes>
</InvoiceLines>
<InvoiceLines>
<LineAmount>500.00</LineAmount>
<SGSRollupItemName></SGSRollupItemName>
<SGSRollupItemNotes></SGSRollupItemNotes>
</InvoiceLines>
</Invoice>
</root>
这是我正在使用的 xslt 代码
<?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"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:key name="dups" match="InvoiceLines[normalize-space(SGSRollupItemName)]" use="concat(generate-id(..), '|', SGSRollupItemName)" />
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<cXML>
<Header/>
<Request xslt="XML">
<InvoiceDetailRequest>
<InvoiceDetailRequestHeader>
</InvoiceDetailRequestHeader>
<xsl:for-each select="Invoice/InvoiceLines[normalize-space(SGSRollupItemName)][not(generate-id() = generate-id(key('dups',concat(generate-id(..), '|', SGSRollupItemName))[1]))]">
<InvoiceDetailOrder>
<InvoiceDetailItem >
<xsl:variable name="numbers">
<xsl:for-each select="key('dups', concat(generate-id(..), '|',SGSRollupItemName ))/LineAmount">
<num>
<xsl:value-of select="translate(., ',', '')"/>
</num>
</xsl:for-each>
</xsl:variable>
<UnitPrice>
<Money>
<xsl:value-of select="format-number(sum(exsl:node-set($numbers)/num),'0.00,#')"/>
</Money>
</UnitPrice>
<NetAmount>
<Money>
<xsl:value-of select="format-number(sum(exsl:node-set($numbers)/num),'0.00,#')"/>
</Money>
</NetAmount>
<Comments>
<xsl:value-of select="./SGSRollupItemName/text()"/>
</Comments>
<Comments>
<xsl:value-of select ="./SGSRollupItemNotes/text()"/>
</Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
</xsl:for-each>
</InvoiceDetailRequest>
</Request>
</cXML>
</xsl:template>
</xsl:stylesheet>
下面是我得到的输出
<?xml version="1.0" encoding="utf-8"?>
<cXML>
<Header />
<Request xslt="XML">
<InvoiceDetailRequest>
<InvoiceDetailRequestHeader />
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>450.00</Money>
</UnitPrice>
<NetAmount>
<Money>450.00</Money>
</NetAmount>
<Comments>Test</Comments>
<Comments>PT</Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
</InvoiceDetailRequest>
</Request>
</cXML>
但下面是预期的输出
<?xml version="1.0" encoding="utf-8"?>
<cXML>
<Header />
<Request xslt="XML">
<InvoiceDetailRequest>
<InvoiceDetailRequestHeader />
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>450.00</Money>
</UnitPrice>
<NetAmount>
<Money>450.00</Money>
</NetAmount>
<Comments>Test</Comments>
<Comments>PT</Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>300.00</Money>
</UnitPrice>
<NetAmount>
<Money>300.00</Money>
</NetAmount>
<Comments>Test1</Comments>
<Comments>PT</Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>400.00</Money>
</UnitPrice>
<NetAmount>
<Money>400.00</Money>
</NetAmount>
<Comments></Comments>
<Comments></Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<InvoiceDetailItem>
<UnitPrice>
<Money>500.00</Money>
</UnitPrice>
<NetAmount>
<Money>500.00</Money>
</NetAmount>
<Comments></Comments>
<Comments></Comments>
</InvoiceDetailItem>
</InvoiceDetailOrder>
</InvoiceDetailRequest>
</Request>
</cXML>
能否请您指出我在 xslt 代码中做错了什么
问题不是很清楚。查看预期的输出,您似乎想要对 SGSRollupItemName
不为空的行进行分组,并分别列出空白的行。
如果是这样,请考虑以下简化示例:
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:key name="dups" match="InvoiceLines" use="concat(generate-id(..), '|', SGSRollupItemName)"/>
<xsl:template match="/root">
<cXML>
<!-- group non-blank items -->
<xsl:for-each select="Invoice/InvoiceLines[normalize-space(SGSRollupItemName)][generate-id() = generate-id(key('dups', concat(generate-id(..), '|', SGSRollupItemName))[1])]">
<InvoiceDetailOrder>
<Money>
<xsl:value-of select="format-number(sum(key('dups', concat(generate-id(..), '|',SGSRollupItemName ))/LineAmount),'0.00')"/>
</Money>
<Comments>
<xsl:value-of select="SGSRollupItemName"/>
</Comments>
</InvoiceDetailOrder>
</xsl:for-each>
<!-- list blank items -->
<xsl:for-each select="Invoice/InvoiceLines[not(normalize-space(SGSRollupItemName))]">
<InvoiceDetailOrder>
<Money>
<xsl:value-of select="LineAmount"/>
</Money>
<Comments>
<xsl:value-of select="SGSRollupItemName"/>
</Comments>
</InvoiceDetailOrder>
</xsl:for-each>
</cXML>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<cXML>
<InvoiceDetailOrder>
<Money>450.00</Money>
<Comments>Test</Comments>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<Money>300.00</Money>
<Comments>Test1</Comments>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<Money>400.00</Money>
<Comments/>
</InvoiceDetailOrder>
<InvoiceDetailOrder>
<Money>500.00</Money>
<Comments/>
</InvoiceDetailOrder>
</cXML>