简体   繁体   中英

PHP - Is it possible to transform XML file to XSL file using xslt transformation

I am trying to generate XSL file based on the XML config file using xsl transformation.

Here is my input.

<front>
   <sample1/>
   <sample2/>
   <sample3>
       <item1/>
       <item2/>
       <item3/>
       <item4/>
   </sample3>
   <sample4/>
</front>

I am expecting to get xsl file like,

<xsl:template match="//div[@class='front']">
    <xsl:apply-templates select=".//*[@class='sample1']"/>
    <xsl:apply-templates select=".//*[@class='sample2']"/>
    <xsl:apply-templates select=".//*[@class='sample3']"/>
    <xsl:apply-templates select=".//*[@class='sample4']"/>
</xsl:template> 
<xsl:template match="//*[@class='sample3']">
    <xsl:apply-templates select=".//*[@class='item1']"/>
    <xsl:apply-templates select=".//*[@class='item2']"/>
    <xsl:apply-templates select=".//*[@class='item3']"/>
    <xsl:apply-templates select=".//*[@class='item4']"/>
</xsl:template> 

Is this can be done using xsl transformation? The main idea is each and every time I make changes in the config file, I no need to write xsl file. It should be generated. If I make changes like,

    <front>
       <sample1/>
       <sample2/>
       <sample4/>
       <sample3>
           <item1/>
           <item2/>
           <item4/>
           <item3/>
       </sample3>
    </front>

The xsl should be,

<xsl:template match="//div[@class='front']">
   <xsl:apply-templates select=".//*[@class='sample1']"/>
   <xsl:apply-templates select=".//*[@class='sample2']"/>
   <xsl:apply-templates select=".//*[@class='sample4']"/>
   <xsl:apply-templates select=".//*[@class='sample3']"/>
</xsl:template> 
   <xsl:template match="//*[@class='sample3']">
   <xsl:apply-templates select=".//*[@class='item1']"/>
   <xsl:apply-templates select=".//*[@class='item2']"/>
   <xsl:apply-templates select=".//*[@class='item4']"/>
   <xsl:apply-templates select=".//*[@class='item3']"/>
</xsl:template>

Any help will be appreciated. Thanks in advance!

There is an example of using XSLT to generate a sttylesheet in the XSLT specification itself: https://www.w3.org/TR/xslt/#element-namespace-alias

Try something like:

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>

<xsl:template match="/">
    <axsl:stylesheet version="1.0">
        <xsl:apply-templates/>
    </axsl:stylesheet>
</xsl:template>

<xsl:template match="/*">
    <axsl:template match="div[@class='{name()}']">
        <xsl:apply-templates mode="apply"/>
    </axsl:template>
    <xsl:apply-templates select="*[*]"/>
</xsl:template>

<xsl:template match="*">
    <axsl:template match="*[@class='{name()}']">
        <xsl:apply-templates mode="apply"/>
    </axsl:template>
    <xsl:apply-templates select="*[*]"/>
</xsl:template>

<xsl:template match="*" mode="apply">
    <axsl:apply-templates select=".//*[@class='{name()}']"/>
</xsl:template>

</xsl:stylesheet>

Note :

  1. A leading // is entirely redundant in a match pattern;

  2. Are you sure you want to have that .// in your xsl:apply-templates select expressions?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM