Saxon XSLT-Компилятор опускает надбавки и сборы

#xslt #saxon #invoice

#xslt #saxon #счет-фактура

Вопрос:

Я использую Saxon XsltTransformer для преобразования XML электронных счетов-фактур («XRechnungen», немецкая адаптация). Счета-фактуры представляют собой XML-файлы с синтаксисом «CII сефакт ООН» или «UBL», и оба они должны быть переведены в один и тот же синтаксис XR.

Для UBL я использую файлы «ubl_invoice_xr.xsl» и «ubl_creditnore_xr.xsl», и это работает без каких-либо проблем.

Для CII я использую «cii_xr.xsl» из https://github.com/itplr-kosit/xrechnung-visualization/tree/master/src/xsl но в результате не учитываются надбавки и расходы (как на уровне invoice_line, так и на уровне документа).

В https://github.com/itplr-kosit/xrechnung-testsuite/tree/master/src/test/business-cases/standard Я нашел много тестовых счетов-фактур (суффикс «uncefact»), но ни один из них не преобразован правильно.

Глядя на «cii-xr.xsl», вы обнаружите:

 <xsl:template mode="BG-20"
                 match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator='false']">

      <xsl:variable name="bg-contents" as="item()*"><!--Der Pfad /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator='false'] der Instanz in konkreter Syntax wird auf 7 Objekte der EN 16931 abgebildet. -->
         <xsl:apply-templates mode="BT-92" select="./ram:ActualAmount"/>
         <xsl:apply-templates mode="BT-93" select="./ram:BasisAmount"/>
         <xsl:apply-templates mode="BT-94" select="./ram:CalculationPercent"/>
         <xsl:apply-templates mode="BT-95" select="./ram:CategoryTradeTax/ram:CategoryCode"/>
         <xsl:apply-templates mode="BT-96" select="./ram:CategoryTradeTax/ram:RateApplicablePercent"/>
         <xsl:apply-templates mode="BT-97" select="./ram:Reason"/>
         <xsl:apply-templates mode="BT-98" select="./ram:ReasonCode"/>
      </xsl:variable>
      <xsl:if test="$bg-contents">
         <xr:DOCUMENT_LEVEL_ALLOWANCES>
            <xsl:attribute name="xr:id" select="'BG-20'"/>
            <xsl:attribute name="xr:src" select="xr:src-path(.)"/>
            <xsl:sequence select="$bg-contents"/>
         </xr:DOCUMENT_LEVEL_ALLOWANCES>
      </xsl:if>
   </xsl:template>
   <xsl:template mode="BT-92"
                 match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge/ram:ActualAmount">
      <xr:Document_level_allowance_amount>
         <xsl:attribute name="xr:id" select="'BT-92'"/>
         <xsl:attribute name="xr:src" select="xr:src-path(.)"/>
         <xsl:call-template name="amount"/>
      </xr:Document_level_allowance_amount>
   </xsl:template>
   <xsl:template mode="BT-93"
                 match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge/ram:BasisAmount">
      <xr:Document_level_allowance_base_amount>
         <xsl:attribute name="xr:id" select="'BT-93'"/>
         <xsl:attribute name="xr:src" select="xr:src-path(.)"/>
         <xsl:call-template name="amount"/>
      </xr:Document_level_allowance_base_amount>
   </xsl:template>
   <xsl:template mode="BT-94"
                 match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge/ram:CalculationPercent">
      <xr:Document_level_allowance_percentage>
         <xsl:attribute name="xr:id" select="'BT-94'"/>
         <xsl:attribute name="xr:src" select="xr:src-path(.)"/>
         <xsl:call-template name="percentage"/>
      </xr:Document_level_allowance_percentage>
   </xsl:template>
   <xsl:template mode="BT-95"
                 match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge/ram:CategoryTradeTax/ram:CategoryCode">
      <xr:Document_level_allowance_VAT_category_code>
         <xsl:attribute name="xr:id" select="'BT-95'"/>
         <xsl:attribute name="xr:src" select="xr:src-path(.)"/>
         <xsl:call-template name="code"/>
      </xr:Document_level_allowance_VAT_category_code>
   </xsl:template>
   <xsl:template mode="BT-96"
                 match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge/ram:CategoryTradeTax/ram:RateApplicablePercent">
      <xr:Document_level_allowance_VAT_rate>
         <xsl:attribute name="xr:id" select="'BT-96'"/>
         <xsl:attribute name="xr:src" select="xr:src-path(.)"/>
         <xsl:call-template name="percentage"/>
      </xr:Document_level_allowance_VAT_rate>
   </xsl:template>
   <xsl:template mode="BT-97"
                 match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge/ram:Reason">
      <xr:Document_level_allowance_reason>
         <xsl:attribute name="xr:id" select="'BT-97'"/>
         <xsl:attribute name="xr:src" select="xr:src-path(.)"/>
         <xsl:call-template name="text"/>
      </xr:Document_level_allowance_reason>
   </xsl:template>
   <xsl:template mode="BT-98"
                 match="/rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge/ram:ReasonCode">
      <xr:Document_level_allowance_reason_code>
         <xsl:attribute name="xr:id" select="'BT-98'"/>
         <xsl:attribute name="xr:src" select="xr:src-path(.)"/>
         <xsl:call-template name="code"/>
      </xr:Document_level_allowance_reason_code>
   </xsl:template>
 

Таким образом, выходной файл должен содержать теги «<xr:DOCUMENT_LEVEL_ALLOWANCES>» с (например)
«</xr:Document_level_allowance_amount>» дочерние элементы, но это не так.
Не имеет значения, есть ли во входном файле надбавки / сборы в «invoice_lines» или на «document_level».

Поскольку я использую vb.NET Я использую .СЕТЕВАЯ оболочка saxon-HE:

  Public Shared Function Cii2UnifiedXML(ByVal vsXmlFilePath As String) As Result
            Dim cproc As New Saxon.Api.Processor
            Dim cComp As Saxon.Api.XsltCompiler = cproc.NewXsltCompiler
            Dim exe As Saxon.Api.XsltExecutable            
            Dim inputStream As New StreamReader(vsXmlFilePath)
#Disable Warning BC40000 ' I know, XmlDataDocument is deprecated
            Dim xmldoc As New XmlDataDocument()
#Enable Warning BC40000
            Dim cResult As New Result
            Dim ctrans As Saxon.Api.XsltTransformer
            Dim seri As Saxon.Api.Serializer
            Dim sPath As String = String.Empty
            Dim sFilename As String = String.Empty
            Dim outStream As FileStream = Nothing

            Try
                exe = cComp.Compile(New MemoryStream(Encoding.UTF8.GetBytes(My.Resources.cii_xr)))
                ctrans = exe.Load
                seri = cproc.NewSerializer
                sPath = Path.GetDirectoryName(vsXmlFilePath)
                sFilename = Path.Combine(sPath, $"{Path.GetFileNameWithoutExtension(vsXmlFilePath)}_Unified.xml")
                outStream = New FileStream(sFilename, FileMode.Create, FileAccess.Write)

                ctrans.SetInputStream(inputStream.BaseStream, New Uri(sPath))
                seri.SetOutputStream(outStream)
                ctrans.Run(seri)

                cResult.Success = True
                cResult.Obj = sFilename
            Catch ex As Exception
                cResult.Exception = ex
                cResult.Success = False
                cResult.ErrorMsg = ex.Message
            Finally
                xmldoc = Nothing
                If outStream IsNot Nothing Then outStream.Close()
                If inputStream IsNot Nothing Then inputStream.Close()
            End Try

            Return cResult
        End Function
 

Я не знаю, не понимаю ли я, как работает XsltCompiler (и, следовательно, я слишком глуп), или это ошибка, поскольку перевод счетов UBL отлично работает.
Выходной файл переводов UBL содержит элементы «DOCUMENT_LEVEL_ALLOWANCES», «DOCUMENT_LEVEL_CHARGES», «INVOICE_LINE_ALLOWANCES» и «INVOICE_LINE_CHARGES».

Все файлы можно найти по адресу https://github.com/itplr-kosit

Большое спасибо

Комментарии:

1. Вы использовали другой процессор XSLT, который дает «правильный» результат? Вы спрашивали разработчиков таблицы стилей, с каким процессором XSLT он должен запускаться? Если вы сомневаетесь в своем VB.NET затем, возможно, сначала запустите Saxon из командной строки, чтобы проверить, выполняют ли таблицы стилей то, что вы от них ожидаете.

2. Привет, Мартин, да, я попробовал другой автономный инструмент, а также xslttest.appspot.com Мои счета-фактуры (реальные и тестовые) не переводятся должным образом. Смотрите мой ответ на комментарий Майкла Кея. Я получил целую кучу счетов-фактур разных компаний с надбавками и сборами, но в каждом отдельном выходном файле они отсутствуют.

3. Вы думаете, что это проблема Saxon? Или используемые таблицы стилей просто не соответствуют заданию с тем конкретным вводом, который у вас есть? Есть ли у людей KoSit какие-либо рекомендации?

4. Я спросил, но KoSit сказал мне, что у них нет команды поддержки разработчиков. Только определения. Я должен спросить разработчиков. Поскольку для версии «Saxon HE» (с открытым исходным кодом) нет поддержки клиентов, они рекомендуют запрашивать в stackoverflow с тегом «saxon», который я использовал. Я уже пробовал это с несколькими (онлайн) инструментами преобразования, и результат всегда уменьшает сборы. Так что да, я думаю, что файл определения «cii-xr.xsl» неисправен. Но он содержит определение для «SpecifiedTradeAllowanceCharge» (см. Комментарии Майкла Кея)

Ответ №1:

Трудно добиться значительного прогресса в отладке этого для вас, потому что я не понимаю словарный запас XML или логику таблицы стилей. Тем не менее, я попробовал это на одном примере документа из тестового набора и правила шаблона, которое вы нам показываете

     <xsl:template mode="BG-20" match="/rsm:CrossIndustryInvoice
        /rsm:SupplyChainTradeTransaction
        /ram:ApplicableHeaderTradeSettlement
        /ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator='false']">
 

не выполняется, потому ApplicableHeaderTradeSettlement что у элемента в исходном документе нет вызываемого дочернего SpecifiedTradeAllowanceCharge элемента .

Конечно, я понятия не имею, что это значит или как это исправить, но нет никаких доказательств того, что таблица стилей не выполняет то, для чего она была разработана, в одном исходном документе, который я тестировал.

Комментарии:

1. Привет, Майкл, большое спасибо за ваш ответ. Да, я заметил, что в / в этих счетах-фактурах есть разные тестовые примеры. Но у меня есть счет-фактура с «SpecifiedTradeAllowanceCharge» в «ApplicableHeaderTradeSettlement». К сожалению, я не могу отправить весь счет-фактуру, поскольку это реальный счет-фактура от реальной компании. Ссылка

2. Если вы не можете предоставить тестовый пример, который демонстрирует сбой, мы не можем сказать вам, почему он не работает.

3. Привет, Майкл, я заменил конфиденциальную информацию на DummyValues и загрузил XML в pastebin: pastebin.com/JS0CFsSM Это один из многих реальных счетов-фактур, которые я получил, и есть «SpecifiedTradeAllowanceCharge» с «ApplicableHeaderTradeSettlement».

Ответ №2:

Сопоставление /rsm:CrossIndustryInvoice/rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeAllowanceCharge[ram:ChargeIndicator='false'] ищет значение false в предикате, в то время как ваш входной образец, похоже, имеет значение true . Так что это может быть одной из причин, по которой указанные вами шаблоны не применяются.

Другой причиной может быть неправильный предикат или отсутствие <xsl:strip-space/> , хотя кажется, что онлайн-XSLT использует правильный предикат [ram:ChargeIndicator/udt:Indicator='false'] , то есть с дополнительным дочерним элементом.

Ответ №3:

проблема была обнаружена, вы не поверите, что ее вызвало… мы попробовали несколько XR-визуализаторов, которые корректно отображали начисления и начисления. Мы попробовали несколько инструментов перевода (web desktop), но ни один из них не создал выходной файл правильно (с надбавками и сборами). Большинство инструментов проверки подлинности для «XPath» отображали счета как «правильные», но только ОДИН сообщил нам, что между элементом «индикатор» и его родительским элементом «ChargeIndicator» есть разрыв строки.

Конечно … везде сотни разрывов строк?

Этот блок в файле накладной cii НЕ работает:

 <ram:ChargeIndicator>
    <udt:Indicator>true</udt:Indicator>
</ram:ChargeIndicator>          
 

но это работает:

 <ram:ChargeIndicator><udt:Indicator>true</udt:Indicator></ram:ChargeIndicator>
 

Я несколько раз пытался связаться с kosit, но у них нет горячей телефонной линии по вопросам разработки, и я не получил ответа на письма, которые я написал 8, 5 и 2 недели назад.

Это забавно, потому что версия XRechnung 2.0 будет обязательной для использования к 1 января 2021 года.

Спасибо за все ваши идеи, ребята