2017-01-02 57 views
0

让我从一个示例开始,按照问题的方式工作。这里是一个非常简单和干净的XML数据:在同一个文档中处理带有XSLT的XSLT输出,将数据平坦化到树节点集

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="flatdata.xsl"?> 

<db> 
<item> 
    <parent></parent> 
    <id>1</id> 
    <title>lorem ipsum</title> 
</item> 

<item> 
    <parent></parent> 
    <id>2</id> 
    <title>dolor sit amet</title> 
</item> 

<item> 
    <parent>1</parent> 
    <id>3</id> 
    <title>consectetur adipiscing elit.</title> 
</item> 

<item> 
    <parent>1</parent> 
    <id>4</id> 
    <title>Nunc varius tempus sem et fringilla</title> 
</item> 

<item> 
    <parent>2</parent> 
    <id>5</id> 
    <title>Aenean egestas</title> 
</item> 

<item> 
    <parent>2</parent> 
    <id>6</id> 
    <title>turpis vel placerat suscipit</title> 
</item> 

<item> 
    <parent>5</parent> 
    <id>7</id> 
    <title>ligula nulla consequat justo</title> 
</item> 
</db> 

这是项目的扁平数据库,用树形结构中潜伏,通过<parent>关系给出。

是转变这嵌套结构揭示item S的树关系的XSLT是非常简单的(我做功课):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="/"> 
    <html> 
     <body> 
      <xsl:apply-templates select="db"/> 
     </body> 
    </html> 
</xsl:template> 

<xsl:template match="db"> 
    <ul> 
     <xsl:apply-templates select="item[parent='']"/> 
    </ul> 
</xsl:template> 

<xsl:template match="item"> 
    <xsl:variable name="vId" select="id"/> 
    <xsl:variable name="vChildren" select="../item[parent=$vId]"/> 
    <li> 
     <b><xsl:value-of select="concat(id,': ')"/></b> <xsl:value-of select="title"/> 
     <xsl:if test="$vChildren"> 
      <ul> 
       <xsl:apply-templates select="$vChildren"/> 
      </ul> 
     </xsl:if> 
    </li> 
</xsl:template> 
</xsl:stylesheet> 

这将产生以下输出:

<ul> 
<li> 
    <b>1: </b>lorem ipsum 
    <ul> 
     <li><b>3: </b>consectetur adipiscing elit.</li> 
     <li><b>4: </b>Nunc varius tempus sem et fringilla</li> 
    </ul> 
</li> 
<li> 
    <b>2: </b>dolor sit amet 
    <ul> 
     <li> 
      <b>5: </b>Aenean egestas 
      <ul> 
       <li> 
        <b>7: </b>ligula nulla consequat justo 
       </li> 
      </ul> 
     </li> 
     <li> 
      <b>6: </b>turpis vel placerat suscipit 
     </li> 
    </ul> 
</li> 
</ul> 

这种情况是,为了我的目的,这个嵌套(树)结构更容易使用XSLT进行处理。我可以使用简单的XPath等来分析哪些item有多少个后代等等。我从源代码收到的XML数据是平坦的,没有什么我可以做的。

那么,怎样才能一个

  1. 识别和创建树结构是一些格式(不必是当然的HTML,那就难免会有一些内部格式,或节点集?)和
  2. 进一步使用XSLT本身在同一样式表上处理该树?

我想在现代浏览器上通过XSLT显示flatdata基本结果,所以我想这意味着我坚持使用1.0(正确?)。

回答

0

可以在XSLT的任何版本创建一个全局变量<xsl:variable name="rtf"><xsl:apply-templates/></xsl:variable>,但是在XSLT 1.0,你会再有一个结果树片段,你只能xsl:copy-of输出,但不使用XPath导航,除非您在使用扩展功能像exsl:node-set<xsl:variable name="ns" select="exsl:node-set($rtf)" xmlns:exsl="http://exslt.org/common"/>。但是,在IE浏览器和Edge不支持exsl:node-set的情况下,内部浏览器出现问题,只有专有的msxsl:node-set位于不同的名称空间(xmlns:msxsl="urn:schemas-microsoft-com:xslt")中。使用扩展功能可以欺骗IE识别exsl:node-set,但该方法在Edge中不起作用。因此,在跨浏览器的XSLT 1.0中,您只需使用xsl:choose/xsl:when/xsl:if即可使用例如。 function-available('exsl:node-set')支持哪个函数,然后将结果树片段转换为节点集。

作为一种替代方案,您可以考虑将Saxon-CE或Saxon-JS带入XSLT 2.0中,以便不存在对结果树片段的限制。