我制作了一个 xslt 脚本,将 XML Peppol/UBL 发票转换为可以导入到我们的 ERP 系统中的 xml 格式。该脚本使用以下命令在 Powershell 中完美运行:
$xsl=’ C:\temp\Axtension_UBL_TEST2.xslt’
$xslt.Load($xsl)
$xslt.Transform($_, $output)
直到我决定使用 Document() 函数将部分脚本与脚本外部的供应商参数一起引入。然后我收到以下错误:
使用“2”个参数调用“Transform”时出现异常:“禁止执行‘document()’函数。使用 XsltSettings.EnableDocumentFunction 属性启用它。
然后我将 powershell 转换脚本更改为:
$XsltSettings = New-Object System.Xml.Xsl.XsltSettings
$XsltSettings.EnableDocumentFunction = 1
$XmlUrlResolver = New-Object System.Xml.XmlUrlResolver
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.Load($xsl, $XsltSettings,$XmlUrlResolver)
$xslt.Transform($_, $output)
我现在收到以下错误,现在我陷入困境。有人可以帮我吗?
$xslt.Transform($_, $output) 使用“2”个参数调用“Transform”时出现异常:“加载文档“Vendors.xml”时发生错误。有关错误的完整描述,请参阅 InnerException。”
Vendors.xml 指的是 xslt 脚本中的文件名,用于将文件加载到 xslt 中。 Axtension_UBL_TEST2.xslt’ 和 Vendors.xml 都位于同一文件夹中,并且拼写(大写)正确。
我也不知道如何使用 InnerException 使完整的错误可见。
这是 xslt 脚本的工作部分,它在 Powershell 中生成相同的错误:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ccts="urn:un:unece:uncefact:documentation:2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns:default="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" exclude-result-prefixes="cac cbc ccts qdt udt default">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<PurchaseInvoices_version_1.0>
<xsl:for-each select="default:Invoice">
<PurchaseInvoice>
<xsl:variable name="current-vendor-name" select="cac:AccountingSupplierParty/cac:Party/cac:PartyName/cbc:Name"/>
<xsl:variable name="vendor-data" select="document('Vendors3.xml')/vendors/vendor[name=$current-vendor-name and administration='XYZ']"/>
<xsl:variable name="VendorShortName" select="$vendor-data/shortName"/>
<xsl:value-of select="$vendor-data"/>
</PurchaseInvoice>
</xsl:for-each>
</PurchaseInvoices_version_1.0>
</xsl:template>
</xsl:stylesheet>
Vendors3.xml 文件包含以下内容:
<vendors>
<vendor>
<administration>XYZ</administration>
<name>TestVendor</name>
<shortName>Tvendor</shortName>
<accountNumber>20250</accountNumber>
<invoiceType/>
<IncludeOrderReference>No</IncludeOrderReference>
<lineText>ItemName</lineText>
<lines>Yes</lines>
</vendor>
</vendors>
用于输入的xml是:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ccts="urn:un:unece:uncefact:documentation:2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cbc:UBLVersionID>2.1</cbc:UBLVersionID>
<cbc:CustomizationID>urn:www.cenbii.eu:transaction:biitrns010:ver2.0:extended:urn:www.peppol.eu:bis:peppol4a:ver2.0</cbc:CustomizationID>
<cbc:ProfileID>urn:www.cenbii.eu:profile:bii04:ver2.0</cbc:ProfileID>
<cac:AccountingSupplierParty>
<cac:Party>
<cac:PartyName>
<cbc:Name>TestVendor</cbc:Name>
</cac:PartyName>
</cac:Party>
</cac:AccountingSupplierParty>
</Invoice>
使用像 Oxygen 这样的 xslt 编辑器时的输出给出以下输出“
<?xml version="1.0" encoding="utf-8"?>
<PurchaseInvoices_version_1.0>
<PurchaseInvoice>
XYZ
TestVendor
Tvendor
20250
No
ItemName
Yes
</PurchaseInvoice>
</PurchaseInvoices_version_1.0
我使用 TransformXML 脚本(使用 $Xslt_Settings.EnableDocumentFunction = 1 )来执行此操作,这似乎提供了有关错误的更多信息:禁止解析外部 URI
InnerException 打印如下:
SourceUri :
LineNumber : 0
LinePosition : 0
Message : An error occurred while loading document 'Vendors.xml'. See InnerException for a complete description of the error.
TargetSite : System.Xml.XPath.XPathNavigator GetDataSource(System.String, System.String)
Data : {}
InnerException : System.Xml.XmlException: Resolving of external URIs was prohibited.
at System.Xml.XmlNullResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
at System.Xml.Xsl.Runtime.XmlQueryContext.GetDataSource(String uriRelative, String uriBase)
HelpLink :
Source : System.Private.Xml
HResult : -2146231998
StackTrace : at System.Xml.Xsl.Runtime.XmlQueryContext.GetDataSource(String uriRelative, String uriBase)
at <xsl:template match="/">(XmlQueryRuntime , XPathNavigator )
at Root(XmlQueryRuntime )
at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer)
at System.Xml.Xsl.XslCompiledTransform.Transform(String inputUri, String resultsFile)
at CallSite.Target(Closure , CallSite , Object , Object , Object )
使用
XslCompiledTransform
及其 Transform/4
方法。我在使用 PowerShell 7.4 时遇到了同样的问题,以下方法对我有用。
$XmlUrlResolver = New-Object System.Xml.XmlUrlResolver
$XsltSettings = New-Object System.Xml.Xsl.XsltSettings($true, $true)
$XsltParams = New-Object System.Xml.Xsl.XsltArgumentList
$XslInputElement = New-Object System.Xml.Xsl.XslCompiledTransform
$XSLWriterSettings = New-Object System.Xml.XmlWriterSettings
$XSLWriterSettings.Indent = $True
$XSLWriterSettings.IndentChars = " "
$XSLWriterSettings.NewLineChars ="`r`n"
$XSLWriterSettings.Encoding = New-Object System.Text.UTF8Encoding $False
$XSLWriter = [System.Xml.XmlWriter]::Create("output.xml", $XSLWriterSettings)
$InFile = New-Object System.Xml.XPath.XPathDocument("input.xml")
$XslInputElement.Load("transform.xslt", $XsltSettings, $XmlUrlResolver)
$XslInputElement.Transform($InFile, $XsltParams, $XSLWriter, $XmlUrlResolver)
使用
XsltSettings($true, $true)
也很重要,因为它可以使用 document
功能。
当然,具体的编写器设置与此无关,但关键是能够使用接受 URL 解析器的
Transform
版本。此外,使用 XslTransform
似乎会悄无声息地失败,并在转换中产生一个空数据集。