2015-04-01 113 views
2

我試圖使用Muenchian分組以分層方式顯示公司策略文檔。策略文檔全部添加到SharePoint,並使用語言,類別和文檔類型進行標記。然後我使用這個創建的XML。將兄弟節點作爲一個用於XSLT Muenchian分組

我需要從2個合併列表中獲取數據。 SharePoint的工作方式,我的XML看起來像這樣(每個SharePoint列表都有一個Rows元素):我不得不簡化它以移除數百個SP在添加到stackoverflowsize限制時添加的屬性,但結構是準確的。

<dsQueryResponse> 
    <Rows> 
    <Row Title="Testitem" Category="Category 1" Language="English" DocumentType="Content" /> 
    </Rows> 
    <Rows> 
    <Row Title="Doc1" Category="Category 1" Language="English" DocumentType="Policy" /> 
    <Row Title="Policy2" Category="Category 2" Language="English" DocumentType="Policy" /> 
    <Row Title="Policy3" Category="Category 1" Language="Nederlands (Dutch)" DocumentType="Form" /> 
    </Rows> 
</dsQueryResponse> 

當前XSL是這樣的:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:SharePoint="Microsoft.SharePoint.WebControls" 
    xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" 
    xmlns:agg="http://schemas.microsoft.com/sharepoint/aggregatesource" 
    xmlns:asp="http://schemas.microsoft.com/ASPNET/20" 
    xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" 
    xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" 
    xmlns:ddwrt2="urn:frontpage:internal" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:x="http://www.w3.org/2001/XMLSchema" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xsl msxsl ddwrt" 
    ddwrt:oob="true" 
> 
    <xsl:output indent="yes" omit-xml-declaration="yes" /> 
    <xsl:key name="byLANGUAGE" match="/dsQueryResponse/Rows/Row" use="@Language" /> 
    <xsl:key name="byCATEGORY" match="/dsQueryResponse/Rows/Row" use="concat(@Language, '+', @Category)" /> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="/dsQueryResponse/Rows/Row[count(. | key('byLANGUAGE', @Language)[1]) = 1]/@Language"> 
     <xsl:sort select="." order="ascending" /> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="@Language"> 
    <br /><b>Below you can see all policies in <xsl:value-of select="." /></b><br /><br /> 
    <xsl:variable name="thisLanguage" select="key('byLANGUAGE', .)" /> 
    <xsl:apply-templates select="$thisLanguage[count(. | key('byCATEGORY', concat(@Language, '+', @Category))[1])= 1]/@Category"> 
     <xsl:sort select="." order="ascending" /> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="@Category"> 
    <br />Category: <xsl:value-of select="." /> 
    <xsl:apply-templates select="key('byCATEGORY', concat(../@Language, '+', .))" /> 
    </xsl:template> 

    <xsl:template match="/dsQueryResponse/Rows/Row"> 
    <br />Title: <xsl:value-of select="@Title" /> 
    </xsl:template> 
</xsl:stylesheet> 

和當前結果看起來像這樣(一團糟):

 
Below you can see all policies in English 

Category: Category 1 
Title: Testitem 

Category: Category 2 
Title: Policy2 

Below you can see all policies in English 

Category: Category 1 
Title: Testitem 

Category: Category 2 
Title: Policy2 

Below you can see all policies in Nederlands (Dutch) 

Category: Category 1 
Title: Policy3 

**My desired output is:** 

Below you can see all policies in English 

Category: Category 1 
Title: Testitem 
Title: Doc1 

Category: Category 2 
Title: Policy2 

Below you can see all policies in Nederlands (Dutch) 

Category: Category 1 
Title: Policy3 

所以,我似乎獲得了大量的可能是因爲某些事情被調用了兩次,每次行爲元素一次?我是XSL的新手,所以任何幫助,將不勝感激。

========== ========== UPDATE

現在下面的代碼對我的作品在SharePoint(笨重面色選擇語句在技術上不必要的,但我需要他們擺脫非英文字符JQuery的,我已經把在此之上)的:

全部XSLT:

<xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:agg="http://schemas.microsoft.com/sharepoint/aggregatesource" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal" ddwrt:oob="true"> 

<xsl:output indent="yes" omit-xml-declaration="yes"/> 
<xsl:key name="byLANGUAGE" match="/dsQueryResponse/Rows/Row" use="@Language" /> 
<xsl:key name="byCATEGORY" match="/dsQueryResponse/Rows/Row" use="concat(@Language, '+', @Category)" /> 

<xsl:template match="/"> 
<div id="tabs" style="display:none;"> 
<!--Create tabs--> 
<ul> 
<xsl:apply-templates select="/dsQueryResponse/Rows/Row[count(. | key('byLANGUAGE', @Language)[2]) = 1]/@Language"> 
<xsl:sort select="." order="ascending" /> 
</xsl:apply-templates> 
</ul> 
<!--Create content--> 
<xsl:apply-templates select="/dsQueryResponse/Rows/Row[count(. | key('byLANGUAGE', @Language)[2]) = 1]/@Language" mode="pass2"> 
<xsl:sort select="." order="ascending" /> 
</xsl:apply-templates> 
</div> 
</xsl:template> 

<!--Do a first pass to create the tabs --> 
<xsl:template match="@Language"> 
<li> 
<xsl:choose> 
<xsl:when test=". = 'English'"><xsl:text disable-output-escaping="yes">&lt;a href="#English"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Bahasa'"><xsl:text disable-output-escaping="yes">&lt;a href="#Bahasa"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = '簡體中文 (Chinese)'"><xsl:text disable-output-escaping="yes">&lt;a href="#Chinese"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Nederlands (Dutch)'"><xsl:text disable-output-escaping="yes">&lt;a href="#Dutch"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Français (French)'"><xsl:text disable-output-escaping="yes">&lt;a href="#French"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Deutsch (German)'"><xsl:text disable-output-escaping="yes">&lt;a href="#German"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Italiano (Italian)'"><xsl:text disable-output-escaping="yes">&lt;a href="#Italian"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = '日本語 (Japanese)'"><xsl:text disable-output-escaping="yes">&lt;a href="#Japanese"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = '한국의 (Korean)'"><xsl:text disable-output-escaping="yes">&lt;a href="#Korean"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Polski (Polish)'"><xsl:text disable-output-escaping="yes">&lt;a href="#Polish"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Português (Portuguese)'"><xsl:text disable-output-escaping="yes">&lt;a href="#Portuguese"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'PyccĸИЙ (Russian)'"><xsl:text disable-output-escaping="yes">&lt;a href="#Russian"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Castellano (Spanish)'"><xsl:text disable-output-escaping="yes">&lt;a href="#Spanish"&gt;</xsl:text><xsl:value-of select="." /><xsl:text disable-output-escaping="yes">&lt;/a&gt;</xsl:text></xsl:when> 
</xsl:choose> 
</li> 
</xsl:template> 

<!--and a second pass to do everything else--> 
<xsl:template match="@Language" mode="pass2"> 
<xsl:choose> 
<xsl:when test=". = 'English'"><xsl:text disable-output-escaping="yes">&lt;div id="English"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Bahasa'"><xsl:text disable-output-escaping="yes">&lt;div id="Bahasa"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = '簡體中文 (Chinese)'"><xsl:text disable-output-escaping="yes">&lt;div id="Chinese"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Nederlands (Dutch)'"><xsl:text disable-output-escaping="yes">&lt;div id="Dutch"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Français (French)'"><xsl:text disable-output-escaping="yes">&lt;div id="French"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Deutsch (German)'"><xsl:text disable-output-escaping="yes">&lt;div id="German"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Italiano (Italian)'"><xsl:text disable-output-escaping="yes">&lt;div id="Italian"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = '日本語 (Japanese)'"><xsl:text disable-output-escaping="yes">&lt;div id="Japanese"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = '한국의 (Korean)'"><xsl:text disable-output-escaping="yes">&lt;div id="Korean"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Polski (Polish)'"><xsl:text disable-output-escaping="yes">&lt;div id="Polish"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Português (Portuguese)'"><xsl:text disable-output-escaping="yes">&lt;div id="Portuguese"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'PyccĸИЙ (Russian)'"><xsl:text disable-output-escaping="yes">&lt;div id="Russian"&gt;</xsl:text></xsl:when> 
<xsl:when test=". = 'Castellano (Spanish)'"><xsl:text disable-output-escaping="yes">&lt;div id="Spanish"&gt;</xsl:text></xsl:when> 
</xsl:choose> 
<b>Below you can see all policies in <xsl:value-of select="." /></b><br /><br/> 

<div class="accordion"> 
<xsl:variable name="thisLanguage" select="key('byLANGUAGE', .)" /> 
<xsl:apply-templates select="$thisLanguage[count(. | key('byCATEGORY', concat(@Language, '+', @Category))[2])= 1]/@Category"> 
<xsl:sort select="." order="ascending" /> 
</xsl:apply-templates> 
</div> 

<xsl:text disable-output-escaping="yes">&lt;/div&gt;</xsl:text> 
</xsl:template> 

<xsl:template match="@Category"> 
<h3> 
<xsl:value-of select="." /> 
</h3> 

<div class="accordionContent"> 
<xsl:apply-templates select="key('byCATEGORY', concat(../@Language, '+', .))"/> 
</div> 
</xsl:template> 

<xsl:template match="/dsQueryResponse/Rows/Row"> 
<div class="policy-item"> 
<div class="policy-item-title"> 
<xsl:value-of select="@Title" /> 
</div> 
<xsl:if test="@ItemHtml != ''"> 
<div class="policy-item-content"> 
<xsl:value-of select="@ItemHtml" disable-output-escaping="yes" /> 
</div> 
</xsl:if> 
</div> 
</xsl:template> 

</xsl:stylesheet> 
+1

這絕對是你的XML看起來的樣子嗎?我在http://xsltransform.net/jyH9rMz上試過了你的XSLT,輸出對我來說確實很好。如果您是新手,那麼您絕對不會錯過XSLT的開始! – 2015-04-01 12:11:55

+0

一類有錯誤的上下文,但除此之外,我認爲這種方法很好,請參閱http://xsltransform.net/gWmuiJx/1。您將需要使用真正的XSLT('>'永遠不會工作)和真正的XML編輯您的問題,在您的示例輸入 – 2015-04-01 12:12:21

+0

中看不到英文'Category:Category 2 Title:Policy2'謝謝 - 我已經糾正了代碼,對不起,XML是錯誤的。因此,如果XSLT和XML都正確並且在xsltransform.net上工作,那麼我只能假設SharePoint沒有正確處理轉換?我正在使用DataView Web部件並將XSLT應用於此。 Tim,之前我做過很多XSLT,但是我從來沒有機會真正學過它,所以有很多反覆試驗和錯誤的習慣,可能還有壞習慣! – Dave 2015-04-01 12:25:41

回答

1

這裏是我會做什麼:

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:SharePoint="Microsoft.SharePoint.WebControls" 
    xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" 
    xmlns:agg="http://schemas.microsoft.com/sharepoint/aggregatesource" 
    xmlns:asp="http://schemas.microsoft.com/ASPNET/20" 
    xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" 
    xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" 
    xmlns:ddwrt2="urn:frontpage:internal" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:x="http://www.w3.org/2001/XMLSchema" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="msxsl ddwrt SharePoint __designer agg asp d ddwrt2 x" 
    ddwrt:oob="true" 
> 
    <xsl:output method="html" indent="yes" omit-xml-declaration="yes" /> 
    <xsl:key name="kRowByLanguage" match="Row" use="@Language" /> 
    <xsl:key name="kRowByCategory" match="Row" use="concat(@Language, '+', @Category)" /> 

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

    <xsl:template match="Rows"> 
    <xsl:apply-templates mode="language" select="Row[ 
     count(. | key('kRowByLanguage', @Language)[1]) = 1 
    ]"> 
     <xsl:sort select="@Language" order="ascending" /> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="Row" mode="language"> 
    <xsl:variable name="myCategory" select="concat(@Language, '+', @Category)" /> 
    <div class="language"> 
     <div> 
     <xsl:text>Below you can see all policies in </xsl:text> 
     <xsl:value-of select="@Language" /> 
     </div> 
     <div> 
     <xsl:apply-templates mode="category" select="key('kRowByLanguage', @Language)[ 
      count(. | key('kRowByCategory', $myCategory)[1]) = 1 
     ]"> 
      <xsl:sort select="@Category" order="ascending" /> 
     </xsl:apply-templates> 
     </div> 
    </div> 
    </xsl:template> 

    <xsl:template match="Row" mode="category"> 
    <xsl:variable name="myCategory" select="concat(@Language, '+', @Category)" /> 
    <div class="catecory"> 
     <div> 
     <xsl:text>Category: </xsl:text> 
     <xsl:value-of select="@Category" /> 
     </div> 
     <div> 
     <xsl:apply-templates mode="title" select="key('kRowByCategory', $myCategory)" /> 
     </div> 
    </div> 
    </xsl:template> 

    <xsl:template match="Row" mode="title"> 
    <div> 
     <xsl:text>Title: </xsl:text> 
     <xsl:value-of select="@Title" /> 
    </div> 
    </xsl:template> 
</xsl:stylesheet> 

輸出(我一般建議使用CSS格式化你的輸出,而不是使用<br>):

<html> 
    <body> 
     <div class="language"> 
     <div>Below you can see all policies in English</div> 
     <div> 
      <div class="catecory"> 
       <div>Category: Category 1</div> 
       <div> 
        <div>Title: Testitem</div> 
        <div>Title: Doc1</div> 
       </div> 
      </div> 
     </div> 
     </div> 
     <div class="language"> 
     <div>Below you can see all policies in Nederlands (Dutch)</div> 
     <div> 
      <div class="catecory"> 
       <div>Category: Category 1</div> 
       <div> 
        <div>Title: Policy3</div> 
       </div> 
      </div> 
     </div> 
     </div> 
    </body> 
</html> 

主要的變化是羣密鑰的舉動(語言+類別)爲變量$myCategory,這使您可以在雙組中選擇正確的節點。

你的原始表達式:

$thisLanguage[count(. | key('byCATEGORY', concat(@Language, '+', @Category))[1])= 1] 

指謂詞(它指的是$thisLanguage,不具有@language或@Category)內錯誤的上下文。將concat(...)移出此表達式會生成正確的結果。

輔助更改是在輸出中添加一些結構,以便通過CSS更輕鬆地進行定位。

另請注意輸出方法和使用不同的模板模式。

一般提示:樣式表中有很多名稱空間聲明。刪除樣式表中不主動使用的任何內容。

+0

謝謝 - 當我在SharePoint之外測試它時,它完美地工作,但是當我在SharePoint中嘗試它時,仍會給出奇怪的結果。看起來這只是一個SharePoint錯誤,而不是任何XSLT問題,我無能爲力。作爲參考,似乎xsltlistviewwebpart正確處理XSLT,但dataformwebpart不處理。不幸的是,只有後者纔會讓我組合兩組數據。我還應該接受這個答案嗎?我是新來的stackoverflow,所以不知道禮儀! – Dave 2015-04-02 09:38:28

+0

我無法想象一個Sharepoint錯誤負責。 Sharepoint內的所有組件都使用.NET集成的XSLT處理器,該處理器足夠成熟,可排除任何錯誤。這是一個非常強烈的跡象表明它已連接到源XML。如果您發佈* exact *源XML和「怪異」結果,它可能會有所幫助。 – Tomalak 2015-04-02 09:58:29

+0

我想通了,但它仍然沒有任何意義,所以我很想聽聽有沒有人能向我解釋這個......爲了讓Muenchian在SharePoint中工作,我必須更改'[count(。| key(' (1)] = 1]'[count(。| key('byLANGUAGE',@Language)[2])= 1]',對於第一類也是一樣的。現在一切正常。 – Dave 2015-04-02 10:56:06