重新编号发票 LineNumber 标签并使用 xslt 将 NaN 替换为 0
Renumber invoice LineNumber tags and replace NaN with 0 using xslt
很抱歉再次打扰您,但我正在努力重新开始使用 XSLT。在我所做的所有搜索中,我看不到这些问题的答案。不知道你学过 XSLT 的人能帮帮我吗..
我在 XML 收到发票,其中有 3 个问题需要处理:
问题 1 是我们得到贷方票据并且一些 LineNumber 标签为 0(如果两个有 0 那么我们的导入失败,因为 table 行在发票/贷方上有唯一索引ref 和行号(很好))。
问题 2 是新供应商在我们初始订单后添加的行号增加 10000 和 x 10 因此如果我们订购了 3 行并且他们添加了两行,发票上的行号是1,2,3 10040 和 10050。我们的(疯狂的)接收 table 的行号最大值为 255。
问题 3 是 InvoicedQuantity 行级别标记中的某些值偶尔会出现 NaN,而我们的 table 具有小数类型。
我对保留行号没有兴趣,因此为了处理这些问题我希望:
- 如果 NaN
,则将标签 InvoicedQuantity 和其他受影响标签的值更改为 0
- 按物理顺序将 LineNumber 标签从 1 重置为最大值
这是一个示例 XML 文件(被截断以仅包含强制问题)
<?xml version="1.0" encoding="UTF-8"?>
<Invoice>
<InvoiceHeader>
<InvoiceReferences>
<InvoiceReference>ABC123</InvoiceReference>
<InvoiceDate>2020-03-11</InvoiceDate>
</InvoiceReferences>
<CostCentreCode>H020</CostCentreCode>
</InvoiceHeader>
<InvoiceDetail>
<InvoiceLine>
<LineNumber>0</LineNumber>
<SuppliersProductCode>A0</SuppliersProductCode>
<BuyersProductCode>ABC120</BuyersProductCode>
<ProductDescription>Product Z</ProductDescription>
<InvoicedQuantity UnitOfMeasure="EA">2</InvoicedQuantity>
<PackSize>1</PackSize>
<UnitValueExclVAT>5</UnitValueExclVAT>
<LineValueExclVAT>10</LineValueExclVAT>
<VATCode>Z</VATCode>
<VATRate>0.00</VATRate>
</InvoiceLine>
<InvoiceLine>
<LineNumber>1</LineNumber>
<SuppliersProductCode>A1</SuppliersProductCode>
<BuyersProductCode>ABC123</BuyersProductCode>
<ProductDescription>Product A</ProductDescription>
<InvoicedQuantity UnitOfMeasure="EA">2</InvoicedQuantity>
<PackSize>1</PackSize>
<UnitValueExclVAT>7.45</UnitValueExclVAT>
<LineValueExclVAT>18.70</LineValueExclVAT>
<VATCode>Z</VATCode>
<VATRate>0.00</VATRate>
</InvoiceLine>
<InvoiceLine>
<LineNumber>10020</LineNumber>
<SuppliersProductCode>B1</SuppliersProductCode>
<BuyersProductCode>ABC1456</BuyersProductCode>
<ProductDescription>Product B</ProductDescription>
<InvoicedQuantity UnitOfMeasure="EA">NaN</InvoicedQuantity>
<PackSize>1</PackSize>
<UnitValueExclVAT>7.45</UnitValueExclVAT>
<LineValueExclVAT>NaN</LineValueExclVAT>
<VATCode>Z</VATCode>
<VATRate>0.00</VATRate>
</InvoiceLine>
</InvoiceDetail>
<InvoiceTrailer>
</InvoiceTrailer>
</Invoice>
这是一个经过修改的身份转换,对 LineNumber 和 InvoicedQuantity 进行了特殊处理,希望对您有所帮助。
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match='InvoiceDetail'>
<xsl:element name='InvoiceDetail'>
<xsl:for-each select='InvoiceLine'>
<xsl:copy>
<!-- Create a sequential line # -->
<xsl:element name='LineNumber'>
<xsl:value-of select='position()'/>
</xsl:element>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:element>
</xsl:template>
<!-- Templates to handle our special cases -->
<xsl:template match='LineNumber'>
<!-- Nothing, get rid of the existing line #s -->
</xsl:template>
<xsl:template match='InvoicedQuantity'>
<xsl:element name='InvoicedQuantity'>
<xsl:apply-templates select="@*"/>
<!-- Convert NaN to 1 -->
<xsl:if test='(.="NaN")'>1</xsl:if>
<xsl:if test='not(.="NaN")'><xsl:value-of select='.'/></xsl:if>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
将这些模板与 XSLT-1.0 结合使用 身份模板:
将 NaN
值替换为 0
<xsl:template match="InvoiceLine/InvoicedQuantity[text()='NaN']">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:value-of select="'0'" />
</xsl:copy>
</xsl:template>
并按照文档顺序对所有以 1
开头的 LineNumber
重新编号:
<xsl:template match="InvoiceLine/LineNumber">
<xsl:copy>
<xsl:value-of select="count(../preceding-sibling::InvoiceLine)+1" />
</xsl:copy>
</xsl:template>
很抱歉再次打扰您,但我正在努力重新开始使用 XSLT。在我所做的所有搜索中,我看不到这些问题的答案。不知道你学过 XSLT 的人能帮帮我吗..
我在 XML 收到发票,其中有 3 个问题需要处理:
问题 1 是我们得到贷方票据并且一些 LineNumber 标签为 0(如果两个有 0 那么我们的导入失败,因为 table 行在发票/贷方上有唯一索引ref 和行号(很好))。
问题 2 是新供应商在我们初始订单后添加的行号增加 10000 和 x 10 因此如果我们订购了 3 行并且他们添加了两行,发票上的行号是1,2,3 10040 和 10050。我们的(疯狂的)接收 table 的行号最大值为 255。
问题 3 是 InvoicedQuantity 行级别标记中的某些值偶尔会出现 NaN,而我们的 table 具有小数类型。
我对保留行号没有兴趣,因此为了处理这些问题我希望:
- 如果 NaN ,则将标签 InvoicedQuantity 和其他受影响标签的值更改为 0
- 按物理顺序将 LineNumber 标签从 1 重置为最大值
这是一个示例 XML 文件(被截断以仅包含强制问题)
<?xml version="1.0" encoding="UTF-8"?>
<Invoice>
<InvoiceHeader>
<InvoiceReferences>
<InvoiceReference>ABC123</InvoiceReference>
<InvoiceDate>2020-03-11</InvoiceDate>
</InvoiceReferences>
<CostCentreCode>H020</CostCentreCode>
</InvoiceHeader>
<InvoiceDetail>
<InvoiceLine>
<LineNumber>0</LineNumber>
<SuppliersProductCode>A0</SuppliersProductCode>
<BuyersProductCode>ABC120</BuyersProductCode>
<ProductDescription>Product Z</ProductDescription>
<InvoicedQuantity UnitOfMeasure="EA">2</InvoicedQuantity>
<PackSize>1</PackSize>
<UnitValueExclVAT>5</UnitValueExclVAT>
<LineValueExclVAT>10</LineValueExclVAT>
<VATCode>Z</VATCode>
<VATRate>0.00</VATRate>
</InvoiceLine>
<InvoiceLine>
<LineNumber>1</LineNumber>
<SuppliersProductCode>A1</SuppliersProductCode>
<BuyersProductCode>ABC123</BuyersProductCode>
<ProductDescription>Product A</ProductDescription>
<InvoicedQuantity UnitOfMeasure="EA">2</InvoicedQuantity>
<PackSize>1</PackSize>
<UnitValueExclVAT>7.45</UnitValueExclVAT>
<LineValueExclVAT>18.70</LineValueExclVAT>
<VATCode>Z</VATCode>
<VATRate>0.00</VATRate>
</InvoiceLine>
<InvoiceLine>
<LineNumber>10020</LineNumber>
<SuppliersProductCode>B1</SuppliersProductCode>
<BuyersProductCode>ABC1456</BuyersProductCode>
<ProductDescription>Product B</ProductDescription>
<InvoicedQuantity UnitOfMeasure="EA">NaN</InvoicedQuantity>
<PackSize>1</PackSize>
<UnitValueExclVAT>7.45</UnitValueExclVAT>
<LineValueExclVAT>NaN</LineValueExclVAT>
<VATCode>Z</VATCode>
<VATRate>0.00</VATRate>
</InvoiceLine>
</InvoiceDetail>
<InvoiceTrailer>
</InvoiceTrailer>
</Invoice>
这是一个经过修改的身份转换,对 LineNumber 和 InvoicedQuantity 进行了特殊处理,希望对您有所帮助。
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match='InvoiceDetail'>
<xsl:element name='InvoiceDetail'>
<xsl:for-each select='InvoiceLine'>
<xsl:copy>
<!-- Create a sequential line # -->
<xsl:element name='LineNumber'>
<xsl:value-of select='position()'/>
</xsl:element>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:element>
</xsl:template>
<!-- Templates to handle our special cases -->
<xsl:template match='LineNumber'>
<!-- Nothing, get rid of the existing line #s -->
</xsl:template>
<xsl:template match='InvoicedQuantity'>
<xsl:element name='InvoicedQuantity'>
<xsl:apply-templates select="@*"/>
<!-- Convert NaN to 1 -->
<xsl:if test='(.="NaN")'>1</xsl:if>
<xsl:if test='not(.="NaN")'><xsl:value-of select='.'/></xsl:if>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
将这些模板与 XSLT-1.0 结合使用 身份模板:
将
NaN
值替换为0
<xsl:template match="InvoiceLine/InvoicedQuantity[text()='NaN']"> <xsl:copy> <xsl:copy-of select="@*" /> <xsl:value-of select="'0'" /> </xsl:copy> </xsl:template>
并按照文档顺序对所有以
1
开头的LineNumber
重新编号:<xsl:template match="InvoiceLine/LineNumber"> <xsl:copy> <xsl:value-of select="count(../preceding-sibling::InvoiceLine)+1" /> </xsl:copy> </xsl:template>