首页 > 解决方案 > 名称空间作为使用 XSLT 处理的文档的变量

问题描述

问题如下,我们需要转换 XML 文件,我们的客户给我们发送了 4 个不同的文件,每个文件都有不同的名称,每个文件都有一个唯一的命名空间,但是文档中的元素是相同的。

文件被命名;Supplier_Invoices_1、Supplier_Invoices_2、Supplier_Invoices_3 等没有扩展名,但它们是 XML。

Supplier_Invoices_2 的命名空间是:

xmlns:wd="urn:com.cust.report/Supplier_Invoices_2"

对于发票_1:

"urn:com.cust.report/Supplier_Invoices_1" 

发票_3:

"urn:com.cust.report/Supplier_Invoices_3"

等等等等。

输入 - Supplier_Invoices_2 示例:

<?xml version='1.0' encoding='UTF-8'?>
<wd:Report_Data xmlns:wd="urn:com.cust.report/Supplier_Invoices_2">
    <wd:Report_Entry>
        <wd:CF_LRV_Journal_line_group>
            <wd:Invoice_Number>SI-00026584</wd:Invoice_Number>
            <wd:Supplier_s_Invoice_Number>19031275</wd:Supplier_s_Invoice_Number>
            <wd:Invoice_Date>2019-03-18-07:00</wd:Invoice_Date>
            <wd:Supplier wd:Descriptor="Company X">
                <wd:ID wd:type="WID">d4e89886417501a66aadebf4570da733</wd:ID>
                <wd:ID wd:type="Supplier_Reference_ID">SUP924</wd:ID>
                <wd:ID wd:type="Supplier_ID">S-00000461</wd:ID>
            </wd:Supplier>
            <wd:Transaction_Debit_minus_Credit>1956.92</wd:Transaction_Debit_minus_Credit>          
        </wd:CF_LRV_Journal_line_group>
    </wd:Report_Entry>
</wd:Report_Data>  

XSLT:

<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:wd="urn:com.cust.report/Supplier_Invoices_2">
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">        
     <xsl:param name="XSLPath" select="base-uri()"/>
        <message>
            <data>
                <xsl:for-each select="/wd:Report_Data/wd:Report_Entry/wd:CF_LRV_Journal_line_group" >
                    <Documents>
                        <row>
                            <path>
                                <xsl:value-of select="tokenize($XSLPath,'/')[last()]" />
                            </path>
                            <CardCode>
                                <xsl:value-of select="./wd:Supplier/wd:ID[@wd:type='Supplier_ID']"/>
                            </CardCode>
                        </row>
                    </Documents>
                    <Document_Lines>
                        <row>
                            <Price>
                                <xsl:value-of select="./wd:Transaction_Debit_minus_Credit" />
                            </Price>
                        </row>
                    </Document_Lines>
                </xsl:for-each>
            </data>
        </message>
    </xsl:template>
</xsl:stylesheet>  

输出:

<?xml version="1.0" encoding="UTF-8"?>
<message xmlns:wd="urn:com.cust.report/Supplier_Invoices_2">
   <data>
      <Documents>
         <row>
            <path>Supplier_Invoices_2</path>
            <CardCode>S-00000461</CardCode>
         </row>
      </Documents>
      <Document_Lines>
         <row>
            <Price>1956.92</Price>
         </row>
      </Document_Lines>
   </data>
</message>

我的问题是,如何将我的 XSL 文档中的命名空间设置为它正在处理的文档的变量?

我将 xsl:param 添加到我的 XSL 中。顶部文档前 5 行如下所示:

<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:wd="urn:com.cust.report/$npath" >
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/">        
     <xsl:param name="XSLPath" select="base-uri()"/>
     <xsl:param name="npath" select="tokenize($XSLPath,'/')[last()]" />

输出:

<?xml version="1.0" encoding="UTF-8"?>
<message xmlns:wd="urn:com.cust.report/$npath">
   <data/>
</message>

任何帮助将不胜感激。

标签: xmlxsltxslt-2.0xml-namespaces

解决方案


在 XSLT/XPath 2 及更高版本中,您可以使用名称空间通配符*:foo来选择任何名称空间中具有本地名称的元素,foo因此如果您使用 eg*:Report_Data而不是wd:Report_Data您应该能够处理相同结构但具有不同名称空间的文档就可以了。

作为替代方案,您可以在链中使用样式表,在该链中将不同名称空间中的输入的名称空间规范化为一个公共名称空间,以便您在第二个样式表中使用公共名称空间。


推荐阅读