我们通过使用xslt将Peppol供应商发票转换为另一种xml格式,从而将Peppol供应商发票导入到我们的ERP-系统中。这样的发票的一个例子是:Github: OpenPEPPOL / peppol-bis-invoice-3
我想给我的会计充分自由,在每个ERP供应商发票日记账字段中填充哪些字段。我想让他们从一组预定义的节点中选择使用,例如:
/Invoice/ID /Invoice/IssueDate
/Invoice/AccountingSupplierParty/Party/PartyName/Name
/Invoice/InvoiceLine/InvoicedQuantity
/Invoice/InvoiceLine/Item/Name我从ERP-系统中导入特定的供应商信息,以便在转换过程中使用,例如查找供应商帐户:
<vendors>
<vendor>
<administration>YIT</administration>
<FISCALCODE>04705810150</FISCALCODE>
<accountNumber>20003</accountNumber>
<Offset_LedgerAccount>67123</Offset_LedgerAccount>
<name>A.Manzoni&C. Spa</name>
</vendor>
<vendors>我使用下面的xslt在供应商xml表中查找此信息:
<xsl:variable name="LegalEntity">
<xsl:choose>
<xsl:when test="contains(cac:AccountingCustomerParty/cac:Party/cac:PartyName/cbc:Name, 'Italia')">YIT</xsl:when>
<xsl:otherwise>'UNKNOWN LegalEntity'</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="current-vendor-name" select="cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name"/>
<xsl:variable name="vendor-data" select="document('Vendors.xml')/vendors/vendor[name=$current-vendor-name and administration=$LegalEntity]"/>转换的输出(当应用于链接中的示例输入文件时)当前如下所示:
<?xml version="1.0" encoding="utf-8"?>
<PurchaseInvoices_version_1.0>
<PurchaseInvoice>
<LegalEntity>YIT</LegalEntity>
<SupplierAccountNum>20202</SupplierAccountNum>
<SupplierBankAccount>IBAN32423940</SupplierBankAccount>
<SupplierName>SupplierTradingName Ltd.</SupplierName>
<SupplierCity>London</SupplierCity>
<CurrencyCode>EUR</CurrencyCode>
<AmountExclTax>1325</AmountExclTax>
<AmountInclTax>1656.25</AmountInclTax>
<TaxAmount>331.25</TaxAmount>
<InvoiceId>Snippet1</InvoiceId>
<InvoiceDate>13-11-2017</InvoiceDate>
<PaymentNote>Payment within 10 days, 2% discount</PaymentNote>
<TaxCode>S</TaxCode>
<Lines>
<Line>
<Item>|Description of item</Item>
<Quantity>7</Quantity>
<UnitPrice>400</UnitPrice>
<LineAmount>2800</LineAmount>
<AmountIncl>3500</AmountIncl>
<AmountExcl>2800</AmountExcl>
<TaxAmount>700</TaxAmount>
<TaxCode>S</TaxCode>
<Description>Description of item|2017-11-13</Description>
<Unit>pcs</Unit>
</Line>
<Line>
<Item>|Description 2</Item>
<Quantity>-3</Quantity>
<UnitPrice>500</UnitPrice>
<LineAmount>-1500</LineAmount>
<AmountIncl>-1875</AmountIncl>
<AmountExcl>-1500</AmountExcl>
<TaxAmount>-375</TaxAmount>
<TaxCode>S</TaxCode>
<Description>Description 2|2017-11-13</Description>
<Unit>pcs</Unit>
</Line>
</Lines>
</PurchaseInvoice>
</PurchaseInvoices_version_1.0>我希望在Description字段中创建更多关于输入xml中要使用的文本(节点)以及显示它们的顺序的自由。这应该定义为供应商卡上的每个供应商,并导入到上面显示的示例的vendors.xml文件中。
例如,对于供应商A,描述可以是所有节点的连接:
/Invoice/ID /Invoice/IssueDate
/Invoice/InvoiceLine/Item/Name
/Invoice/InvoiceLine/InvoicedQuantity
/Invoice/AccountingSupplierParty/Party/PartyName/Name 而对供应商B的说明只能是:
/Invoice/InvoiceLine/Item/Name问题是如何从这里着手。
我目前的想法是根据固定数量的变量创建一个描述:
<Description><xsl:value-of select="$A"/><xsl:value-of select="$B"/><xsl:value-of select="$C"/><xsl:value-of select="$D"/></Description>并根据Vendor卡上的某种输入在每个变量中放置正确的节点,Vendor卡导入到vendors.xml文件中并在xslt中使用。
发布于 2022-10-11 10:03:51
按照您最初的想法,使用数字代码对描述中包含的值的顺序进行处理,请考虑下面的示例,这个示例非常简化。
XML
<Invoice>
<ID>001</ID>
<DueDate>2002-01-01</DueDate>
<LineItem>
<Name>Widget</Name>
<Quantity>5</Quantity>
<Description>Description of widget</Description>
</LineItem>
<LineItem>
<Name>Gadget</Name>
<Quantity>17</Quantity>
<Description>Description of gadget</Description>
</LineItem>
</Invoice>XSLT1.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:param name="reorder">030102</xsl:param>
<xsl:template match="/Invoice">
<PurchaseInvoice Id="{ID}">
<!-- ... -->
<xsl:for-each select="LineItem">
<Line>
<!-- ... -->
<Description>
<xsl:call-template name="reorder">
<xsl:with-param name="nodes" select="../DueDate | Name | Description"/>
<xsl:with-param name="order" select="$reorder"/>
</xsl:call-template>
</Description>
</Line>
</xsl:for-each>
</PurchaseInvoice>
</xsl:template>
<xsl:template name="reorder">
<xsl:param name="nodes" select="/.."/>
<xsl:param name="order"/>
<xsl:value-of select="$nodes[number(substring($order, 1 , 2))]"/>
<xsl:if test="string-length($order) > 2">
<xsl:text> | </xsl:text>
<!-- recursive call -->
<xsl:call-template name="reorder">
<xsl:with-param name="nodes" select="$nodes"/>
<xsl:with-param name="order" select="substring($order, 3)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>结果
<?xml version="1.0" encoding="UTF-8"?>
<PurchaseInvoice Id="001">
<Line>
<Description>Description of widget | 2002-01-01 | Widget</Description>
</Line>
<Line>
<Description>Description of gadget | 2002-01-01 | Gadget</Description>
</Line>
</PurchaseInvoice>为了保持这一点的简单性,您必须将数字代码按输入XML中的顺序分配给nodes参数中列出的值。
在本例中,代码是一个全局参数;在您的实现中,您将希望从供应商文档中检索它。
添加:
如果愿意,可以使用描述性字符串而不是数字代码来选择顺序。但是,样式表变得更加复杂:
XSLT1.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:param name="reorder">description|due date|name</xsl:param>
<xsl:template match="/Invoice">
<PurchaseInvoice Id="{ID}">
<!-- ... -->
<xsl:for-each select="LineItem">
<Line>
<!-- ... -->
<Description>
<xsl:call-template name="reorder">
<xsl:with-param name="order" select="$reorder"/>
</xsl:call-template>
</Description>
</Line>
</xsl:for-each>
</PurchaseInvoice>
</xsl:template>
<xsl:template name="reorder">
<xsl:param name="order"/>
<xsl:param name="delimiter" select="'|'"/>
<xsl:variable name="token" select="substring-before(concat($order, $delimiter), $delimiter)" />
<xsl:choose>
<xsl:when test="$token='due date'">
<xsl:value-of select="../DueDate"/>
</xsl:when>
<xsl:when test="$token='name'">
<xsl:value-of select="Name"/>
</xsl:when>
<xsl:when test="$token='description'">
<xsl:value-of select="Description"/>
</xsl:when>
</xsl:choose>
<xsl:if test="contains($order, $delimiter)">
<xsl:text> | </xsl:text>
<!-- recursive call -->
<xsl:call-template name="reorder">
<xsl:with-param name="order" select="substring-after($order, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>https://stackoverflow.com/questions/74014428
复制相似问题