2014-12-05 63 views
0

我拥有可具有可变数目的子元素的XML。
当有超过“N”个子元素时,我们需要一种方法来添加展开/折叠功能。
示例XMLxsl在“N”个子元素之后展开和折叠

<?xml version="1.0"?> 
<TestXML> 
    <N>Test</N> 
    <NTList> 
     <NT> 
      <NT1>NT1 Test 1</NT1> 
      <NT2>NT2 Test 1</NT2> 
     </NT> 
     <NT> 
      <NT1>NT1 Test 2</NT1> 
      <NT2>NT2 Test 2</NT2> 
     </NT> 
     <NT> 
      <NT1>NT1 Test 3</NT1> 
      <NT2>NT2 Test 3</NT2> 
     </NT> 
    </NTList> 
</TestXML> 

因此,在这个例子中,我们想补充的展开/折叠如果有超过2“NT”里面的“NTList”。

我认为this是接近的,但我无法找到一种方法来确定何时在达到“N”记录后添加展开/折叠。

东西很基本的像这样的HTML输出:

N : Test 
NTLIST 
    NT (1) 
     NT1 : NT1 Test 1 
     NT2 : NT2 Test 1 
    NT (2) 
     NT1 : NT1 Test 2 
     NT2 : NT2 Test 2 
    NT (+More) <- where this is the link to click to expand the 3rd NT. 

回答

0

如您有jQuery的作为标签我觉得以下解决方案可以为你工作。您可以在xsl:for-each循环中使用position()来确定第N条记录。如实施例,对于N = 3:

XSLT:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 
<xsl:output method="html" doctype-public="XSLT-compat" 
    omit-xml-declaration="yes" encoding="UTF-8" indent="yes" /> 
    <xsl:template match="TestXML"> 
    <ul> 
     <li>N : Test<br/>NTLIST 
     <xsl:for-each select="NTList/NT">  
      <ul> 
      <li> 
       <xsl:if test="position() >=3"> 
       <xsl:attribute name="class" select="'toggle'"/> 
       </xsl:if> 
       <xsl:value-of select=" 
       if(position() &lt; 3) 
       then concat(local-name(), ' (', position(),')') 
       else concat(local-name(), ' (+More)')"/> 
       <ul> 
        <xsl:if test="position() >=3"> 
        <xsl:attribute name="class" select="'hidden'"/> 
        </xsl:if> 
        <xsl:for-each select="*"> 
        <li> 
         <xsl:value-of select="."/> 
        </li> 
        </xsl:for-each> 
       </ul> 
      </li> 
      </ul> 
     </xsl:for-each> 
     </li> 
    </ul> 
    </xsl:template> 
</xsl:transform> 

当施加到您的输入XML产生输出中(相关部分):

<ul> 
    <li>N : Test<br/>NTLIST 
     <ul> 
     <li>NT (1) 
      <ul> 
       <li>NT1 Test 1</li> 
       <li>NT2 Test 1</li> 
      </ul> 
     </li> 
     </ul> 
     <ul> 
     <li>NT (2) 
      <ul> 
       <li>NT1 Test 2</li> 
       <li>NT2 Test 2</li> 
      </ul> 
     </li> 
     </ul> 
     <ul> 
     <li class="toggle">NT (+More) 
      <ul class="hidden"> 
       <li>NT1 Test 3</li> 
       <li>NT2 Test 3</li> 
      </ul> 
     </li> 
     </ul> 
    </li> 
</ul> 

以下CSS隐藏具有hidden类列表并从列表元素中删除了要点:

ul 
{ 
    list-style-type:none; 
} 
.hidden 
{ 
    display:none;) 
} 

而且foll由于jQuery:

$(".toggle").on("click", function() { 
    $(this).find("ul").slideToggle(); 
}); 

将切换隐藏列表。刚刚添加了一个Fiddle的结果。

参考:position()http://api.jquery.com/slidetoggle/

更新:正如在评论中提到,建议的方法,因为在select属性使用if和使用selectxsl:attribute的OP设置(Visual Studio中)不工作。下面的XSLT使用xsl:when语句生成相同的输出。我无法测试它是否可以在Visual Studio中工作,但如果不能,您可以添加一个带有新错误的注释。

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
<xsl:output method="html" doctype-public="XSLT-compat" 
omit-xml-declaration="yes" encoding="UTF-8" indent="yes" /> 
    <xsl:template match="TestXML"> 
    <ul> 
     <li> 
      N : Test<br/> 
      NTLIST 
      <xsl:for-each select="NTList/NT"> 
       <ul> 
        <li> 
         <xsl:if test="position() >=3"> 
         <xsl:attribute name="class">toggle</xsl:attribute> 
         </xsl:if> 
         <xsl:choose> 
         <xsl:when test="position() &lt; 3"> 
          <xsl:value-of 
           select="concat(local-name(), ' (', position(),')')"/> 
         </xsl:when> 
         <xsl:otherwise> 
          <xsl:value-of 
           select="concat(local-name(), ' (+More)')"/> 
         </xsl:otherwise> 
         </xsl:choose> 
         <ul> 
         <xsl:if test="position() >=3"> 
          <xsl:attribute name="class">hidden</xsl:attribute>  
         </xsl:if> 
         <xsl:for-each select="*"> 
          <li> 
          <xsl:value-of select="."/> 
          </li> 
         </xsl:for-each> 
         </ul> 
        </li> 
       </ul> 
      </xsl:for-each> 
     </li> 
    </ul> 
    </xsl:template> 
</xsl:transform> 

更新:正如评论所说,我忽略了修改两处select -statements在xsl:attribute。通过调整到例如<xsl:attribute name="class">hidden</xsl:attribute>。为了避免空格或换行符这种的情况下,潜在的问题可以通过添加<xsl:text>作为包装进行更改:

<xsl:attribute name="class"> 
    <xsl:text>hidden</xsl:text> 
</xsl:attribute> 
+0

您发布的代码不会在我的IDE“VS”工作。例如,select中的if(position)给了我错误“if()是未知的XSLT函数”。在xsl:属性上的select也给我错误“select是xsl:attribute元素的无效属性”。我正在研究“xsl:choose”替换“if(position)”,但如果您知道某种方法可以使此代码在Visual Studio或IE中工作,我将非常感谢。感谢您的帮助。 – goroth 2014-12-06 02:51:53

+0

@goroth很高兴能有所帮助。我刚刚通过调整后的XSLT更新了我的答案。我无法在VS中进行测试,但可以尝试一下,如果发现新错误,请添加评论。 – 2014-12-06 19:49:03

+0

您的原始代码与xsl:if工作,但是select = if没有,所以您不必更改所有if来选择语句。唯一仍然不起作用的是xsl:attribute select。所以我将它改为 toggle。我会发布我的完整的代码在一个编辑上面我看它/使用jquery更好地工作。 – goroth 2014-12-07 18:39:23