2017-04-21 60 views
0

我想產生的數據的樹,看起來像這樣分隔文本:XSL 1.0創建HTML UL-華里的XPath,其中數據以XML樹屬性由「/」

    • 1stGenChild1
      • 2ndGenChild1
      • 2ndGenChild2
    • 1stGenChild2

等產生的代碼如下:

<ul> 
    <li>root</li> 
    <ul> 
    <li>1stGenChild1</li> 
    <ul> 
    <li>2ndGenChild1</li> 
    <li>2ndGenChild2</li> 
    </ul> 
    <li>1stGenChild2</li> 
</ul> 

在我的數據的格式爲:

<XML_FILTER> 
    <XPATH @xpath="root/1stGenChild1" /> 
    <XPATH @xpath="root/1stGenChild1/2ndGenChild1" /> 
    <XPATH @xpath="root/1stGenChild1/2ndGenChild2" /> 
    <XPATH @xpath="root/1stGenChild2" /> 
</XML_FILTER> 

這將是相對簡單的生產這種在使用tokenise的XSLT2中,但是我不能使用XSLT2,因爲我僅限於正在使用的系統使用MSXML 6.0。

我發現的最大問題是這樣做的正常方法無法處理從未在其屬性中明確聲明的根,但我仍然需要在輸出中使用此節點。

我該如何生成可能有更多子節點級別的數據樹? - 即。列表中的列表比上面顯示的示例多得多。

也沒有人知道是否有列表內的列表數量限制之前,不會由瀏覽器呈現縮進,因爲這會使視圖無用。

非常感謝。

+0

「*這樣做不能與屬性數據之中,而不是在元素的內部處理的正常方法。*」這有什麼區別?你指的是什麼「常規方法」? –

+0

經過反思,我認爲我的情況不同在於我的數據中的第一個xpath不是根,它是第一個孩子。我仍然希望得到相同的輸出,並且擁有它自己的水平。我已經調整了相應的問題。 –

+0

提前知道根元素的名稱嗎? –

回答

1

下面是根據它們的層次嵌套節點的簡單方法:

XSLT 1.0

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

<xsl:template match="/XML_FILTER"> 
    <ul> 
     <xsl:apply-templates select="XPATH[not(contains(@xpath, '/'))]"/> 
    </ul> 
</xsl:template> 

<xsl:template match="XPATH"> 
    <xsl:variable name="dir" select="concat(@xpath, '/')" /> 
    <li> 
     <xsl:value-of select="@xpath"/> 
    </li> 
    <xsl:variable name="child" select="../XPATH[starts-with(@xpath, $dir) and not(contains(substring-after(@xpath, $dir), '/'))]" /> 
    <xsl:if test="$child"> 
     <ul> 
      <xsl:apply-templates select="$child"/> 
     </ul>   
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

適用於您的示例輸入(從屬性的名字移除非法@字符後! ),結果將爲:

<?xml version="1.0" encoding="UTF-8"?> 
<ul> 
    <li>root</li> 
    <ul> 
    <li>root/1stGenChild1</li> 
    <ul> 
     <li>root/1stGenChild1/2ndGenChild1</li> 
     <li>root/1stGenChild1/2ndGenChild2</li> 
    </ul> 
    <li>root/1stGenChild2</li> 
    </ul> 
</ul> 

現在您只需要替換:

一起返回的最後一個令牌的命名模板調用
<xsl:value-of select="@xpath"/> 

指令 - 參見:https://stackoverflow.com/a/41625340/3016153


還是這樣做,而不是:

XSLT 1。0

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

<xsl:template match="/XML_FILTER"> 
    <ul> 
     <xsl:apply-templates select="XPATH[not(contains(@xpath, '/'))]"/> 
    </ul> 
</xsl:template> 

<xsl:template match="XPATH"> 
    <xsl:param name="parent"/> 
    <xsl:variable name="dir" select="concat(@xpath, '/')" /> 
    <li> 
     <xsl:value-of select="substring-after(concat('/', @xpath), concat($parent, '/'))"/> 
    </li> 
    <xsl:variable name="child" select="../XPATH[starts-with(@xpath, $dir) and not(contains(substring-after(@xpath, $dir), '/'))]" /> 
    <xsl:if test="$child"> 
     <ul> 
      <xsl:apply-templates select="$child"> 
       <xsl:with-param name="parent" select="concat('/', @xpath)"/> 
      </xsl:apply-templates> 
     </ul>   
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 
+0

非常好的解決方案,但不是我需要的輸出。我如何修改這個以僅顯示子ul元素中路徑的最後部分,以便輸出與我的描述相匹配? (即,看起來像具有本機路徑的目錄結構,而不是在每個級別顯示絕對路徑) –

+1

你有沒有看完整個答案? –