2017-08-04 55 views
1

我有多个xml/xhtml文件,我需要将列表中的列表进行转换。列表可以有两种不同的格式。我已经展示了每个清单的例子,并且它是理想的结果。示例1中的XSLT正常工作,但示例2中都使用了apply-templates employeesList和employeesList2模式。任何帮助获得理​​想的结果将不胜感激。使用XSLT更改XML/XHTML中的列表

实施例1:

<div class="company1"> 
    <div class="employees-companyLabel">Employees:</div> 
    <ol class="company-employees"> 
     <li class="company-employee">Joe Smith</li> 
     <li class="company-employee">Dave Jones</li> 
     <li class="company-employee">Bill Williams</li> 
     <li class="company-employee">Steve Hobbs</li> 
     <li class="company-employee">Jim Brown</li> 
    </ol> 
</div> 

期望的结果:

<div class="company2"> 
    <div class="header">Employees:</div> 
    <ul class="employees"> 
     <li class="employee">Joe Smith</li> 
     <li class="employee">Dave Jones</li> 
     <li class="employee">Bill Williams</li> 
     <li class="employee">Steve Hobbs</li> 
     <li class="employee">Jim Brown</li> 
    </ul> 
</div> 

实施例2:

<div class="company1">  
    <div class="employees-companyLabel">Employees:</div> 
    <div class="subhead-employees">Foreman:</div> 
    <ol class="company-employees"> 
     <li class="company-employee">Joe Smith</li> 
     <li class="company-employee">Dave Jones</li> 
    </ol> 
    <div class="subhead-employees">Laborers:</div> 
    <ol class="company-employees"> 
     <li class="company-employee">Bill Williams</li> 
     <li class="company-employee">Steve Hobbs</li> 
     <li class="company-employee">Jim Brown</li> 
    </ol> 
</div> 

期望的结果:

<div class="company2"> 
    <div class="header">Employees:</div> 
    <ul class="employees"> 
     <li class="positionTitle">Foreman</li> 
     <li class="employee">Joe Smith</li> 
     <li class="employee">Dave Jones</li> 
     <li class="positionTitle">Laborers</li> 
     <li class="employee">Bill Williams</li> 
     <li class="employee">Steve Hobbs</li> 
     <li class="employee">Jim Brown</li> 
    </ol> 
</div> 

XSLT:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xhtml"> 
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="xhtml:div[@class='company1']"> 
     <xsl:copy> 
      <xsl:attribute name="class"> 
       <xsl:value-of select="'company2'"/> 
      </xsl:attribute> 
      <xsl:apply-templates select="@*[not(name()='class')]"/> 
      <xsl:apply-templates select="node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="xhtml:div[@class='employees-companyLabel']"> 
     <xsl:copy> 
      <xsl:attribute name="class"> 
       <xsl:value-of select="'header'"/> 
      </xsl:attribute> 
      <xsl:apply-templates select="@*[not(name()='class')]"/> 
      <xsl:value-of select="translate(., ':', '')" /> 
     </xsl:copy> 
     <xsl:element name="ul"> 
      <xsl:attribute name="class">employees</xsl:attribute> 
      <xsl:apply-templates select="./following-sibling::xhtml:ol[@class='company-employees']" mode="employeesList" /> 
      <xsl:apply-templates select="./following-sibling::xhtml:div[@class='subhead-employees']" mode="employeesList2" /> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="xhtml:ol[@class='company-employees']" mode="employeesList"> 
     <xsl:for-each select="xhtml:li[@class='company-employee']"> 
      <xsl:element name="li"> 
       <xsl:attribute name="class">employee</xsl:attribute> 
       <xsl:apply-templates /> 
      </xsl:element> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="xhtml:div[@class='subhead-employees']" mode="employeesList2"> 
     <xsl:element name="li"> 
      <xsl:attribute name="class"> 
       <xsl:value-of select="'positionTitle'"/> 
      </xsl:attribute>  
      <xsl:apply-templates /> 
     </xsl:element> 
     <xsl:for-each select="./following-sibling::xhtml:ol[@class='company-employees'][1]/xhtml:li[@class='company-employee']"> 
      <xsl:element name="li"> 
       <xsl:attribute name="class">employee</xsl:attribute> 
       <xsl:apply-templates /> 
      </xsl:element> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="xhtml:div[@class='subhead-employees']" /> 
    <xsl:template match="xhtml:ol[@class='company-employees']" /> 
    <xsl:template match="xhtml:li[@class='company-employee']" /> 
</xsl:stylesheet> 

回答

1

这是一个非常简单的建议是明确的“填写模板”样式:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xhtml="http://www.w3.org/1999/xhtml" 
    xmlns="http://www.w3.org/1999/xhtml" 
    exclude-result-prefixes="xhtml"> 

    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="xhtml:div[@class='company1']"> 
    <div class="company2"> 
     <div class="header">Employees:</div> 
     <ul class="employees"> 
     <xsl:for-each select="xhtml:div[@class='subhead-employees']|*/xhtml:li"> 
      <li class="{if (@class='subhead-employees') then 'positionTitle' else 'employee'}"> 
      <xsl:value-of select="replace(string(), ':\s*$', '')"/> 
      </li> 
     </xsl:for-each> 
     </ul> 
    </div> 
    </xsl:template> 
</xsl:stylesheet> 

或者,更多的是基于模板匹配的建议:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xhtml="http://www.w3.org/1999/xhtml" 
    xmlns="http://www.w3.org/1999/xhtml" 
    exclude-result-prefixes="xhtml"> 

    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="xhtml:div[@class='company1']"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:attribute name="class" select="'company2'"/> 
     <xsl:apply-templates select="xhtml:div[@class='employees-companyLabel']"/> 
     <ul class="employees"> 
     <xsl:apply-templates select="xhtml:div[@class='subhead-employees']|*/xhtml:li"/> 
     </ul> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="xhtml:div[@class='employees-companyLabel']"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:attribute name="class" select="'header'"/> 
     <xsl:apply-templates select="node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="xhtml:div[@class='subhead-employees']"> 
    <li class="positionTitle"> 
     <xsl:value-of select="translate(., ':', '')"/> 
    </li> 
    </xsl:template> 

    <xsl:template match="xhtml:li"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:attribute name="class" select="'employee'"/> 
     <xsl:apply-templates select="node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet>