XML到固定宽度的文件通过XSLT

时间:2015-04-14 14:31:46

标签: xml xslt

我是XSLT的新手,我正在尝试将XML转换为固定宽度的文件。

XML:

<?xml version="1.0" encoding="utf-8"?>
<Report xsl:version="1.0" xsi:schemaLocation="FPPD2_LLP.srdl http://ss61/ReportServer?%2FSunSystems%2FExample%20Reports%2FProcess%2FFPPD2_LLP.srdl&amp;rs%3AFormat=XML&amp;rc%3ASchema=True" Name="FPPD2.srdl" baseAmount_baseCreditAmount_TOTAL="1032.14" baseAmount_baseCreditAmount_COUNT="3" Today="2015-04-14T02:16:44" DocumentNumber="                41" ExecDate="2015-04-14" ssp_del_rpt_unique_8b128d78f1404199bce7d8b083ceff68="True" xmlns="FPPD2.srdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <Detail_2_1>
        <Detail_2_1_Group_Collection>
            <Item RowNumber="1" transactionDate="2004-04-01" accountCode_label_2="Account Code:" accountCode_3="PK181010" description_1="Telephone" paymentAccount_1="BANK" transactionReference="404TELE001NYC" description_label_2="Description:" description_2="Teleford communications" baseAmount_baseCreditAmount="428.57" baseAmount_baseDebitAmount_x="0.00" baseAmount_amount_1="428.57" baseAmount_baseDebitAmount="" baseAmount_amount_10="-428.57" supplierName_label_1="Supplier Name:" supplierName_1="Teleford &amp; Communications" addressLine1_label_1="Address Line 1:" addressLine1_1="57 Harpermoorish Ave" addressLine2_label_1="Address Line 2:" addressLine2_1="" addressLine3_label_1="Address Line 3:" addressLine3_1="" addressLine4_label_1="Address Line 4:" addressLine4_1="Birmingham  RG5 5BJ" addressLine5_label_1="Address Line 5:" addressLine5_1="UK" TownCity_label_1="Town/City:" TownCity_1="Birmingham" State_label_1="State:" State_1="" StateCode_label_1="State Code:" StateCode_1="" PostalCode_label_1="Postal Code:" PostalCode_1="RG5 5BJ" Country_label_1="Country:" Country_1="UK" document_1="Document:" TextBox_15="404TELE001NYC" bankAccountName_label_1="Bank Account Name:" bankAccountName_1="Travelbug Software Ltd" bankAccountNumber_label_1="Bank Account Number:" bankAccountNumber_1="DE21500500001234567897" BankSortCode_label_1="Bank Sort Code:" BankSortCode_1="BUINBGSF123" BankSubcode_label_1="Bank Subcode:" BankSubcode_1="" BankBranch_label_1="Bank Branch:" BankBranch_1="Southampton" BankDetailsCode_label_1="Bank Details Code:" BankDetailsCode_1="81010" BankName_label_1="Bank Name:" BankName_1="Midland Bank Plc" SwiftCode_label_1="Extension Swift Code:" SwiftCode_1="" />
            <Item RowNumber="2" transactionDate="2004-05-01" accountCode_label_2="Account Code:" accountCode_3="PK181010" description_1="Telephone" paymentAccount_1="BANK" transactionReference="405TELE001NYC" description_label_2="Description:" description_2="Teleford communications" baseAmount_baseCreditAmount="428.57" baseAmount_baseDebitAmount_x="0.00" baseAmount_amount_1="857.14" baseAmount_baseDebitAmount="" baseAmount_amount_10="-857.14" supplierName_label_1="Supplier Name:" supplierName_1="Teleford &amp; Communications" addressLine1_label_1="Address Line 1:" addressLine1_1="57 Harpermoorish Ave" addressLine2_label_1="Address Line 2:" addressLine2_1="" addressLine3_label_1="Address Line 3:" addressLine3_1="" addressLine4_label_1="Address Line 4:" addressLine4_1="Birmingham  RG5 5BJ" addressLine5_label_1="Address Line 5:" addressLine5_1="UK" TownCity_label_1="Town/City:" TownCity_1="Birmingham" State_label_1="State:" State_1="" StateCode_label_1="State Code:" StateCode_1="" PostalCode_label_1="Postal Code:" PostalCode_1="RG5 5BJ" Country_label_1="Country:" Country_1="UK" document_1="Document:" TextBox_15="405TELE001NYC" bankAccountName_label_1="Bank Account Name:" bankAccountName_1="Travelbug Software Ltd" bankAccountNumber_label_1="Bank Account Number:" bankAccountNumber_1="DE21500500001234567897" BankSortCode_label_1="Bank Sort Code:" BankSortCode_1="BUINBGSF123" BankSubcode_label_1="Bank Subcode:" BankSubcode_1="" BankBranch_label_1="Bank Branch:" BankBranch_1="Southampton" BankDetailsCode_label_1="Bank Details Code:" BankDetailsCode_1="81010" BankName_label_1="Bank Name:" BankName_1="Midland Bank Plc" SwiftCode_label_1="Extension Swift Code:" SwiftCode_1="" />
            <Item RowNumber="3" transactionDate="2004-02-01" accountCode_label_2="Account Code:" accountCode_3="PK181015" description_1="Leased Lines" paymentAccount_1="BANK" transactionReference="402TELE003TOK" description_label_2="Description:" description_2="Integration International" baseAmount_baseCreditAmount="175.00" baseAmount_baseDebitAmount_x="0.00" baseAmount_amount_1="1,032.14" baseAmount_baseDebitAmount="" baseAmount_amount_10="-1,032.14" supplierName_label_1="Supplier Name:" supplierName_1="Integration International" addressLine1_label_1="Address Line 1:" addressLine1_1="49, Station Road" addressLine2_label_1="Address Line 2:" addressLine2_1="" addressLine3_label_1="Address Line 3:" addressLine3_1="" addressLine4_label_1="Address Line 4:" addressLine4_1="London  E4 7BJ" addressLine5_label_1="Address Line 5:" addressLine5_1="" TownCity_label_1="Town/City:" TownCity_1="London" State_label_1="State:" State_1="" StateCode_label_1="State Code:" StateCode_1="" PostalCode_label_1="Postal Code:" PostalCode_1="E4 7BJ" Country_label_1="Country:" Country_1="" document_1="Document:" TextBox_15="402TELE003TOK" bankAccountName_label_1="Bank Account Name:" bankAccountName_1="Creditor Account" bankAccountNumber_label_1="Bank Account Number:" bankAccountNumber_1="DE21500500009876543210" BankSortCode_label_1="Bank Sort Code:" BankSortCode_1="CRBABGSF" BankSubcode_label_1="Bank Subcode:" BankSubcode_1="" BankBranch_label_1="Bank Branch:" BankBranch_1="Cambridge" BankDetailsCode_label_1="Bank Details Code:" BankDetailsCode_1="81015" BankName_label_1="Bank Name:" BankName_1="Lloyds Bank" SwiftCode_label_1="Extension Swift Code:" SwiftCode_1="" />
        </Detail_2_1_Group_Collection>
    </Detail_2_1>
</Report>

我用过这个例子:

XML to Fixed width text file with xsl style sheet

期望的输出:

HEADER000001    HARD-CODED STUFF    AA1032.14   CC  DD2015-04-14T02:16:44   NN41
ITEM1   20040401    PK181010    Telephone
ITEM1   404TELE001NYC   Teleford Communications
ITEM2   20040501    PK181010    Telephone
ITEM2   404TELE001NYC   Teleford Communications
ITEM3   20040201    PK181015    Leased Lines
ITEM3   402TELE003TOK   Integration International
FOOTER HARD-CODED STUFf

这是我目前使用的,但它没有生成任何文件,我不知道原因:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:xmlns:FPPD2_LLPINT.srdl" xmlns:ns2="FPPD2_LLPINT.srdl">
    <xsl:output method="text" indent="yes"/>

    <xsl:variable name="some_spaces" select="'                                                                  '" />

    <xsl:template match="/ns2:Report">
        <!-- HEADER -->
        <xsl:text>HEADER000001    </xsl:text>
        <xsl:call-template name="pad">
            <xsl:with-param name="text" select="@DocumentNumber"/>
            <xsl:with-param name="width" select="15"/>
        </xsl:call-template>
        <!-- more calls to complete the header -->
        <xsl:text>&#10;</xsl:text>
        <!-- ITEMS -->
        <xsl:apply-templates select="/ns2:Detail_2_1/ns2:Detail_2_1_Group_Collection/ns2:Item"/>
        <!-- FOOTER -->
        <xsl:text>&#10;FOOTER </xsl:text>
        <xsl:call-template name="pad">
            <xsl:with-param name="text" select="@amount_TOTAL"/>
            <xsl:with-param name="width" select="10"/>
        </xsl:call-template>
        <!-- more calls to complete the footer -->
    </xsl:template>

    <!-- Items list -->
    <xsl:template match="ns2:Item">
        <xsl:apply-templates mode="format" select="@transactionReference">
            <xsl:with-param name="width" select="number(9-1)"/>
        </xsl:apply-templates>
        <xsl:apply-templates mode="format" select="@supplierName_1">
            <xsl:with-param name="width" select="number(17-10)"/>
        </xsl:apply-templates>
    <!-- More iterations  to complete FRIST row with items -->
        <xsl:text>&#10;</xsl:text>
        <xsl:apply-templates mode="format" select="@baseAmount_baseCreditAmount">
            <xsl:with-param name="width" select="number(9-1)"/>
        </xsl:apply-templates>
        <xsl:apply-templates mode="format" select="@bankAccountNumber_1">
            <xsl:with-param name="width" select="number(17-10)"/>
        </xsl:apply-templates>
    <!-- More iterations to complete SECOND row with items -->
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

    <xsl:template name="pad">
        <xsl:param name="text" />
        <xsl:param name="width" />
        <xsl:value-of select="substring(concat(.,$some_spaces ), 1, $width+1)"/>
    </xsl:template>

     <xsl:template  match="@*" mode ="format">
        <xsl:param name="width" />
        <xsl:value-of select="substring(concat(.,$some_spaces), 1, $width+1)"/>
    </xsl:template>
    <xsl:template  match="@*" mode="format_date">
        <xsl:param name="width" />
        <xsl:value-of select="substring(concat(translate(.,'/',''),$some_spaces), 1, $width+1)"/>
    </xsl:template>

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

您有几个问题:

1.您正在使用前缀“ns2”withput将其绑定到命名空间。将其添加到样式表声明中:

xmlns:ns2="FPPD2.srdl"

2.您的主模板与/根节点匹配。从这个背景来看,     指令:

<xsl:apply-templates select="/ns2:Detail_2_1/ns2:Detail_2_1_Group_Collection/ns2:Item"/>

不会选择任何内容,因为Detail_2_1不是根节点的子节点。请尝试改为:

<xsl:apply-templates select="ns2:Report/ns2:Detail_2_1/ns2:Detail_2_1_Group_Collection/ns2:Item"/>

另请注意,在匹配模式中,node() 匹配属性 - 因此将忽略您的格式设置模板以及复制文本值的内置模板规则因此,将被调用。


编辑:

  
      
  1. 如何在第一行放置一些属性(例如DocumentNumber),其中一些属性(例如amount_TOTAL)   在txt文件的最后一行;
  2.   

类似的东西:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ns2="FPPD2.srdl">
<xsl:output method="text"/>

<xsl:variable name="some_spaces" select="'                                                                  '" />

<xsl:template match="/ns2:Report">
    <xsl:text>HEADER000001    </xsl:text>
    <xsl:call-template name="pad">
        <xsl:with-param name="text" select="@DocumentNumber"/>
        <xsl:with-param name="width" select="15"/>
    </xsl:call-template>
    <!-- more calls to complete the header -->
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="ns2:Detail_2_1/ns2:Detail_2_1_Group_Collection/ns2:Item"/>
    <xsl:text>&#10;FOOTER </xsl:text>
    <xsl:call-template name="pad">
        <xsl:with-param name="text" select="@amount_TOTAL"/>
        <xsl:with-param name="width" select="10"/>
    </xsl:call-template>
    <!-- more calls to complete the footer -->
</xsl:template>

<xsl:template match="ns2:Item">
    <!-- ... -->
</xsl:template>

<xsl:template name="pad">
    <xsl:param name="text" />
    <xsl:param name="width" />
    <xsl:value-of select="substring(concat($text, $some_spaces), 1, $width+1)"/>
    <!-- why +1 ? -->
</xsl:template>

</xsl:stylesheet>