Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 基于节点值的递归XSLT1.0_Xml_Xslt_Recursion_Sharepoint 2013_Xslt 1.0 - Fatal编程技术网

Xml 基于节点值的递归XSLT1.0

Xml 基于节点值的递归XSLT1.0,xml,xslt,recursion,sharepoint-2013,xslt-1.0,Xml,Xslt,Recursion,Sharepoint 2013,Xslt 1.0,我试图在XSLT 1.0中实现一个递归(树)列表,该列表从如下所示的XML开始: <list> <row> <icon>http://server/app/icon.gif</icon> <title>Document</title> <location>Root\Formulier</location> </row> <row>

我试图在XSLT 1.0中实现一个递归(树)列表,该列表从如下所示的XML开始:

<list>
  <row>
    <icon>http://server/app/icon.gif</icon>
    <title>Document</title>
    <location>Root\Formulier</location> 
  </row>
  <row>
    <icon>http://server/app/icon.gif</icon>
    <title>Handleiding1</title>
    <location>Root\Handleidingen</location> 
  </row>
  <row>
    <icon>http://server/app/icon.gif</icon>
    <title>Form</title>
    <location>Root\Formulier\Informed consent (IC)</location> 
  </row>
  <row>
    <icon>http://server/app/icon.gif</icon>
    <title>Handleiding2</title>
    <location>Root\Handleidingen</location> 
  </row>
</list>

http://server/app/icon.gif
文件
Root\Formulier
http://server/app/icon.gif
手工打样1
根\Handleidingen
http://server/app/icon.gif
类型
Root\Formulier\知情同意书(IC)
http://server/app/icon.gif
手工打样2
根\Handleidingen
这必须使用XSLT1.0,因为我们的SharePoint还不支持2.0

它应该看起来像Windows资源管理器中的树

我目前拥有的XSLT代码是:

    <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes" />
  <xsl:key name="groups" match="/list/row" use="location" />
  <xsl:template match="/list">
    <div class="idocument-list">
      <xsl:apply-templates select="row[generate-id() = generate-id(key('groups', location)[1])]"/>
    </div>
  </xsl:template>
  <xsl:template match="row">
    <div style="margin-bottom:5px;">
      <ul>
        <li>
          <img border="0" style="align:left;" src="/_layouts/15/images/folder.gif?rev=23" alt="map" />
          <span class="ms-textLarge idocumentlist-title">
            <xsl:value-of select="substring-after(location,'Root\')"/>
          </span>
          <ul style="display:none;">
            <xsl:for-each select="key('groups', location)">
              <li>
                <img border="0" style="align:left;">
                  <xsl:attribute name="src">
                    <xsl:value-of select="icon"/>
                  </xsl:attribute>
                </img>
                <span>
                  <a>
                    <xsl:attribute name="href">
                      <xsl:value-of select="link"/>
                    </xsl:attribute>
                    <xsl:value-of select="title"/>
                  </a>
                </span>
              </li>
            </xsl:for-each>
          </ul>
        </li>
      </ul>
    </div>
  </xsl:template>
</xsl:stylesheet>

其结果如下所示:

例如,“Formulier \知情同意书(IC)”显示每个文件夹之后的所有文件夹,而它应在\上拆分,并显示“Formulier”作为“知情同意书(IC)”的父文件夹。(我将“Root\”位置子串出来,但它应该显示在顶部作为根节点)

示例结果代码:

<div class="idocument-list">
  <ul>
    <li>
      <img style="align: left;" alt="map" src="..." border="0">
      <span class="ms-textLarge idocumentlist-title">Root</span>
      <ul>
        <li>
          <img style="align: left;" alt="map" src="..." border="0">
          <span class="ms-textLarge idocumentlist-title">Formulier</span>
          <ul>
            <li>
              <img style="align: left;" alt="map" src="..." border="0">
              <span class="ms-textLarge idocumentlist-title">Informed consent (IC)</span>
              <ul>
                <li>
                  <img style="align: left;" src="..." border="0">
                  <span>
                    <a href="...">Form</a>
                  </span>
                </li>
              </ul>
            </li>
            <li>
              <img style="align: left;" alt="map" src="..." border="0">
              <span>
                <a href="...">Document</a>
              </span>
            </li>
          </ul>
        </li>
        <li>
          <img style="align: left;" alt="map" src="..." border="0">
          <span class="ms-textLarge idocumentlist-title">Handleidingen</span>
          <ul>
            <li>
              <img style="align: left;" src="..." border="0">
              <span>
                <a href="...">Handleiding1</a>
              </span>
            </li>
            <li>
              <img style="align: left;" src="..." border="0">
              <span>
                <a href="...">Handleiding2</a>
              </span>
            </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</div>

    • 公式制定者
      • 知情同意(IC)
    • 汉德雷丁根
有谁能给我一个信息源或代码,让我用XSLT1.0来实现类似的功能

提前谢谢


尼尔斯

我担心这可能比看起来要复杂得多

  • 如果要为每个文件夹显示一个节点(无论它是否包含 文档),您必须首先将位置标记为 单个文件夹
  • 接下来,必须从结果中消除重复项*
  • 第三步是将文件夹排列成层次结构 并将文档重新附加到其文件夹中
下面是一个草图,可以用作样式表的基础:

XSLT1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="location-by-path" match="location" use="@path" />
<xsl:key name="location-by-parent" match="location" use="@parent-path" />
<xsl:key name="document-by-location" match="row" use="location" />

<xsl:variable name="xml" select="/" />

<!-- 1st pass: tokenize paths to individual locations -->
<xsl:variable name="locations">
    <xsl:for-each select="/list/row">
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="location"/>
        </xsl:call-template>
    </xsl:for-each>
</xsl:variable>

<!-- 2nd pass: distinct locations only -->
<xsl:variable name="distinct-locations">
    <xsl:copy-of select="exsl:node-set($locations)/location[count(. | key('location-by-path', @path)[1]) = 1]"/>
</xsl:variable> 
<xsl:variable name="distinct-locations-set" select="exsl:node-set($distinct-locations)" />

<!-- output -->
<xsl:template match="/list">
    <root>
        <!-- start with progenitor locations  -->
        <xsl:apply-templates select="$distinct-locations-set/location[@parent-path='']"/>
    </root>
</xsl:template>

<xsl:template match="location">
    <xsl:variable name="path" select="@path" />
    <xsl:element name="{@name}">
        <!-- set context to XML input  -->
        <xsl:for-each select="$xml">
            <!-- get documents  -->
            <xsl:apply-templates select="key('document-by-location', $path)"/>
        </xsl:for-each>
        <!-- set context to distinct locations  -->
        <xsl:for-each select="$distinct-locations-set">
            <!-- get subdirectories  -->
            <xsl:apply-templates select="key('location-by-parent', concat($path, '\'))"/>
        </xsl:for-each>
    </xsl:element>
</xsl:template>

<xsl:template match="row">
    <document name="{title}"/>
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="text"/>
    <xsl:param name="parent-path"/>
    <xsl:param name="delimiter" select="'\'"/>
    <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
    <xsl:if test="$token">
        <location name="{$token}" path="{concat($parent-path, $token)}" parent-path="{$parent-path}"/>
    </xsl:if>
    <xsl:if test="contains($text, $delimiter)">
        <!-- recursive call -->
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
            <xsl:with-param name="parent-path" select="concat($parent-path, $token, $delimiter)"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>


</xsl:stylesheet> 

应用于示例输入时,结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <rootfolder>
      <document name="Doc2"/>
      <folder1>
         <document name="Doc3"/>
         <folder1.1>
            <folder1.1.1>
               <document name="Doc1"/>
            </folder1.1.1>
         </folder1.1>
      </folder1>
      <folder2>
         <folder2.1>
            <folder2.1.1>
               <document name="Doc4"/>
            </folder2.1.1>
         </folder2.1>
      </folder2>
   </rootfolder>
</root>



(*)您需要熟悉才能理解此解决方案。

请将预期结果显示为代码。我的错,我添加了示例!这与这个问题几乎相同:@Tomalak这是不同的,因为在这里您需要为每个不同的位置步骤创建一个节点,而不仅仅是为每个文档创建一个节点,就像另一个答案那样。@Devil请将预期结果显示为代码(2)。