首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT:从多个节点填充字符串怎么处理这事?

XSLT:从多个节点填充字符串怎么处理这事?
EN

Stack Overflow用户
提问于 2022-10-10 11:45:40
回答 1查看 87关注 0票数 0

我们通过使用xslt将Peppol供应商发票转换为另一种xml格式,从而将Peppol供应商发票导入到我们的ERP-系统中。这样的发票的一个例子是:Github: OpenPEPPOL / peppol-bis-invoice-3

我想给我的会计充分自由,在每个ERP供应商发票日记账字段中填充哪些字段。我想让他们从一组预定义的节点中选择使用,例如:

代码语言:javascript
复制
/Invoice/ID /Invoice/IssueDate 
/Invoice/AccountingSupplierParty/Party/PartyName/Name 
/Invoice/InvoiceLine/InvoicedQuantity
/Invoice/InvoiceLine/Item/Name

我从ERP-系统中导入特定的供应商信息,以便在转换过程中使用,例如查找供应商帐户:

代码语言:javascript
复制
<vendors>
    <vendor>
        <administration>YIT</administration>
        <FISCALCODE>04705810150</FISCALCODE>
        <accountNumber>20003</accountNumber>
        <Offset_LedgerAccount>67123</Offset_LedgerAccount>
        <name>A.Manzoni&amp;C. Spa</name>
    </vendor>
<vendors>

我使用下面的xslt在供应商xml表中查找此信息:

代码语言:javascript
复制
<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]"/>

转换的输出(当应用于链接中的示例输入文件时)当前如下所示:

代码语言:javascript
复制
<?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,描述可以是所有节点的连接:

代码语言:javascript
复制
/Invoice/ID /Invoice/IssueDate 
/Invoice/InvoiceLine/Item/Name
/Invoice/InvoiceLine/InvoicedQuantity
/Invoice/AccountingSupplierParty/Party/PartyName/Name 

而对供应商B的说明只能是:

代码语言:javascript
复制
/Invoice/InvoiceLine/Item/Name

问题是如何从这里着手。

我目前的想法是根据固定数量的变量创建一个描述:

代码语言:javascript
复制
<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中使用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-11 10:03:51

按照您最初的想法,使用数字代码对描述中包含的值的顺序进行处理,请考虑下面的示例,这个示例非常简化。

XML

代码语言:javascript
复制
<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

代码语言:javascript
复制
<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>

结果

代码语言:javascript
复制
<?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

代码语言:javascript
复制
<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>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74014428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档