XSLT 2.0-默认情况下如何在输出文件中包括属性?

时间:2019-05-21 13:04:15

标签: xslt xslt-2.0

我希望在输入文件中存在的输出文件中包含属性。期望来自输入文件下方,属性ws:PriorValue将包含在转换后的输出文件中

输入文件:

<?xml version="1.0" encoding="UTF-8"?>
<ws:Worker_Sync xmlns:ws="urn:com.workday/workersync" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ws:Worker>
        <ws:Summary>
            <ws:Employee_ID>00013582</ws:Employee_ID>
            <ws:Name>Test Employee</ws:Name>
        </ws:Summary>       
        <ws:Personal>
            <ws:Name_Data>
                <ws:Name_Type>Legal</ws:Name_Type>
                <ws:First_Name>Test</ws:First_Name>
                <ws:Last_Name ws:PriorValue="Worker">Employee</ws:Last_Name>                
            </ws:Name_Data>         
            <ws:Gender ws:PriorValue="">Male</ws:Gender>
            <ws:Birth_Date>1985-12-21</ws:Birth_Date>
            <ws:Address_Data>
                <ws:Address_Type>HOME</ws:Address_Type>
                <ws:Address_Is_Public>false</ws:Address_Is_Public>
                <ws:Is_Primary>true</ws:Is_Primary>
                <ws:Address_Line_Data ws:PriorValue="Address test">Address Sample</ws:Address_Line_Data>
                <ws:Submunicipality ws:PriorValue="Helsinki">Tampere</ws:Submunicipality>
                <ws:Postal_Code ws:PriorValue="00010">01350</ws:Postal_Code>
                <ws:Country>FI</ws:Country>
            </ws:Address_Data>          
        </ws:Personal>
        <ws:Contract>
            <ws:Operation>ADD</ws:Operation>
            <ws:Position_ID ws:PriorValue="P5002970612">P5002970643</ws:Position_ID>
            <ws:Contract_Type ws:PriorValue="Temporary">Permanent</ws:Contract_Type>
            <ws:Start_Date ws:PriorValue="2017-01-01">2017-08-31</ws:Start_Date>            
        </ws:Contract>
    </ws:Worker>
</ws:Worker_Sync>
到目前为止,我创建的

XSLT:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ws="urn:com.workday/workersync" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
    <!--xsl:output encoding="utf-16"/-->
    <xsl:template match="ws:Worker_Sync">
        <Root>
            <xsl:apply-templates select="ws:Worker">
            </xsl:apply-templates>
        </Root>
    </xsl:template>
    <xsl:template match="ws:Worker">
        <Worker>
            <Personal>
                <BirthDate>
                    <xsl:value-of select=" format-date(xs:date(ws:Personal/ws:Birth_Date), '[Y0001][M01][D01]') "/>
                </BirthDate>
                <FirstName>
                    <xsl:value-of select="concat(ws:Personal/ws:Name_Data[ws:Name_Type='Legal']/ws:First_Name, ws:Personal/ws:Name_Data[ws:Name_Type='Legal']/ws:Middle_Name)"/>
                </FirstName>
                <Gender>
                    <xsl:value-of select="if (ws:Personal/ws:Gender='Male') then '1' else '2'"/>
                </Gender>
                <GenderText>
                    <xsl:value-of select="ws:Personal/ws:Gender"/>
                </GenderText>
                <Initials>
                    <xsl:value-of select="concat(ws:Personal/ws:Name_Data[ws:Name_Type='Preferred']/ws:First_Name, ' ', ws:Personal/ws:Name_Data[ws:Name_Type='Preferred']/ws:Last_Name)"/>
                </Initials>
                <Language>
                    <xsl:value-of select="ws:Personal/ws:Birth_Date"/>
                </Language>
                <LastName>
                    <xsl:value-of select="ws:Personal/ws:Name_Data[ws:Name_Type='Legal']/ws:Last_Name"/>
                </LastName>
                <Ssn>
                    <xsl:value-of select="ws:Identification_Data[ws:Identification='National']/ws:ID"/>
                </Ssn>
            </Personal>
            <Contact_Details>
                <CityHome>
                    <xsl:value-of select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Submunicipality"/>
                </CityHome>
                <CountryHome>
                    <xsl:value-of select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Country"/>
                </CountryHome>              
                <StreetAddressHome>
                    <xsl:value-of select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Address_Line_Data"/>
                </StreetAddressHome>
                <ZipCodeHome>
                    <xsl:value-of select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Postal_Code"/>
                </ZipCodeHome>                              
            </Contact_Details>
            <Contract>
                <ContractType>
                    <xsl:value-of select="if (ws:Position/ws:Worker_Type = 'Permanent') then '01' else '02'"/>      
                </ContractType>
                <ContractTypeText>
                    <xsl:value-of select="if (ws:Position/ws:Worker_Type = 'Permanent') then 'Vakituinen' else 'Määräaik. sopimus'"/>               
                </ContractTypeText>
                <ProbationEndDate>
                    <xsl:value-of select="format-date(xs:date(ws:Status/ws:Probation_End_Date), '[Y0001][M01][D01]')"/>         
                </ProbationEndDate>                 
            </Contract>
        </Worker>
    </xsl:template>
</xsl:stylesheet>


输出:


<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:ws="urn:com.workday/workersync" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Worker>
        <Personal>
            <BirthDate>19851221</BirthDate>
            <FirstName>Test</FirstName>
            <Gender>1</Gender>
            <GenderText>Male</GenderText>
            <Initials> </Initials>
            <Language>1985-12-21</Language>
            <LastName>Employee</LastName>
            <Ssn/>
        </Personal>
        <Contact_Details>
            <CityHome>Tampere</CityHome>
            <CountryHome>FI</CountryHome>
            <StreetAddressHome>Address Sample</StreetAddressHome>
            <ZipCodeHome>01350</ZipCodeHome>
        </Contact_Details>
        <Contract>
            <ContractType>02</ContractType>
            <ContractTypeText>Määräaik. sopimus</ContractTypeText>
            <ProbationEndDate/>
        </Contract>
    </Worker>
</Root>

但是我希望获得如下输出文件:

<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:ws="urn:com.workday/workersync" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Worker>
        <Personal>
            <BirthDate>19851221</BirthDate>
            <FirstName>Test</FirstName>
            <Gender>1</Gender>
            <GenderText PriorValue="">Male</GenderText>
            <Initials> </Initials>
            <Language>1985-12-21</Language>
            <LastName PriorValue="Worker">Employee</LastName>
            <Ssn/>
        </Personal>
        <Contact_Details>
            <CityHome PriorValue="Helsinki">Tampere</CityHome>
            <CountryHome>FI</CountryHome>
            <StreetAddressHome PriorValue="Address test">Address Sample</StreetAddressHome>
            <ZipCodeHome PriorValue="00010">01350</ZipCodeHome>
        </Contact_Details>
        <Contract>
            <ContractType>02</ContractType>
            <ContractTypeText>Määräaik. sopimus</ContractTypeText>
            <ProbationEndDate/>
        </Contract>
    </Worker>
</Root>

这可能吗?我不确定是否总能达到这个结果。谢谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您可以在此处使用xsl:attribute元素...

<ZipCodeHome>
    <xsl:attribute name="PriorValue" select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Postal_Code/@ws:PriorValue" />
    <xsl:value-of select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Postal_Code"/>
</ZipCodeHome>

但是您也可以使用属性值模板。...

<ZipCodeHome PriorValue="{ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Postal_Code/@ws:PriorValue}">
    <xsl:value-of select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Postal_Code"/>
</ZipCodeHome>    

但是如果您要复制的属性不是PriorValue,请考虑编写通用模板来处理它们

<xsl:template match="@*">
  <xsl:attribute name="{local-name()}" select="." />
</xsl:template>

那你要写这个...

<ZipCodeHome>
    <xsl:apply-templates select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Postal_Code/@*" />
    <xsl:value-of select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']/ws:Postal_Code"/>
</ZipCodeHome>

但是无论哪种情况,XSLT都与XPath表达式有很多重复,因此请考虑使用模板匹配来缩短内容。...

尝试使用此XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ws="urn:com.workday/workersync" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
    <xsl:output encoding="utf-16" method="xml" indent="yes" />

    <xsl:template match="ws:Worker_Sync">
        <Root>
            <xsl:apply-templates select="ws:Worker" />
        </Root>
    </xsl:template>

    <xsl:template match="ws:Worker">
        <Worker>
            <xsl:apply-templates select="ws:Personal" />
            <xsl:apply-templates select="ws:Personal/ws:Address_Data[ws:Address_Type='HOME']" />
            <Contract>
                <ContractType>
                    <xsl:value-of select="if (ws:Position/ws:Worker_Type = 'Permanent') then '01' else '02'"/>      
                </ContractType>
                <ContractTypeText>
                    <xsl:value-of select="if (ws:Position/ws:Worker_Type = 'Permanent') then 'Vakituinen' else 'Määräaik. sopimus'"/>               
                </ContractTypeText>
                <ProbationEndDate>
                    <xsl:value-of select="format-date(xs:date(ws:Status/ws:Probation_End_Date), '[Y0001][M01][D01]')"/>         
                </ProbationEndDate>                 
            </Contract>
        </Worker>
    </xsl:template>

    <xsl:template match="ws:Personal">
        <Personal>
            <BirthDate>
                <xsl:value-of select="format-date(xs:date(ws:Birth_Date), '[Y0001][M01][D01]') "/>
            </BirthDate>
            <FirstName>
                <xsl:value-of select="concat(ws:Name_Data[ws:Name_Type='Legal']/ws:First_Name, ws:Name_Data[ws:Name_Type='Legal']/ws:Middle_Name)"/>
            </FirstName>
            <Gender>
                <xsl:value-of select="if (ws:Gender='Male') then '1' else '2'"/>
            </Gender>
            <GenderText>
                <xsl:apply-templates select="ws:Gender"/>
            </GenderText>
            <Initials>
                <xsl:value-of select="concat(ws:Name_Data[ws:Name_Type='Preferred']/ws:First_Name, ' ', ws:Name_Data[ws:Name_Type='Preferred']/ws:Last_Name)"/>
            </Initials>
            <Language>
                <xsl:apply-templates select="ws:Birth_Date"/>
            </Language>
            <LastName>
                <xsl:apply-templates select="ws:Name_Data[ws:Name_Type='Legal']/ws:Last_Name"/>
            </LastName>
            <Ssn>
                <xsl:apply-templates select="ws:Identification_Data[ws:Identification='National']/ws:ID"/>
            </Ssn>
        </Personal>        
    </xsl:template>


    <xsl:template match="ws:Address_Data">
        <Contact_Details>
            <CityHome>
                <xsl:apply-templates select="ws:Submunicipality" />
            </CityHome>
            <CountryHome>
                <xsl:apply-templates select="ws:Country"/>
            </CountryHome>              
            <StreetAddressHome>
                <xsl:apply-templates select="ws:Address_Line_Data"/>
            </StreetAddressHome>
            <ZipCodeHome>
                <xsl:apply-templates select="ws:Postal_Code"/>
            </ZipCodeHome>                              
        </Contact_Details>        
    </xsl:template>

    <xsl:template match="*">
        <xsl:apply-templates select="@*" />
        <xsl:value-of select="."/>
    </xsl:template>

    <xsl:template match="@*">
      <xsl:attribute name="{local-name()}" select="." />
    </xsl:template>
</xsl:stylesheet>