问题
I am new to XSLT programming and struggling with the following issue:
XML:
<All_Results>
<Result>
<url>http://server/sites/sitecoll/library/Folder/NewFolder/test v1.0.docx</url>
<hithighlightedproperties>
<HHUrl>SomeValue1</HHUrl>
</hithighlightedproperties>
<isdocument>True</isdocument>
<serverredirectedurl>SomeValue</serverredirectedurl>
</Result>
<Result>
<url>http://server/sites/sitecoll/library/NewFolder1/test v2.0.docx</url>
<hithighlightedproperties>
<HHUrl>SomeValue1</HHUrl>
</hithighlightedproperties>
<isdocument>True</isdocument>
<serverredirectedurl>SomeValue</serverredirectedurl>
</Result>
<Result>
<url>http://server/sites/sitecoll/library/NewFolder/test v1.0.docx</url>
<hithighlightedproperties>
<HHUrl>SomeValue1</HHUrl>
</hithighlightedproperties>
<isdocument>False</isdocument>
<serverredirectedurl>SomeValue1</serverredirectedurl>
</Result>
......
......
Following is the requirement:
For each "Result" section, if ("isdocument" node = True), read the "url" node and get substring after 'library/' in it's value. From this output, get the substring before the last occurrence of '/'. (Used separate a template to achieve this) For example, for the first "Result", it will be "Folder/NewFolder". Finally, concatenate hard-coded strings before and after this output and replace the values of "HHUrl" and "ServerRedirectUrl" with this final output for every "Result" under "Results".
Output
<All_Results>
<Result>
<url>http://server/sites/sitecoll/library/Folder/NewFolder/test v1.0.docx</url>
<hithighlightedproperties>
<HHUrl>http://SomeHardCodedString1/Folder/NewFolder/SomeHardCodedString2</HHUrl>
</hithighlightedproperties>
<isdocument>True</isdocument>
<serverredirectedurl>
http://SomeHardCodedString1/Folder/NewFolder/SomeHardCodedString2
</serverredirectedurl>
</Result>
<Result>
<url>http://server/sites/sitecoll/library/NewFolder1/test v2.0.docx</url>
<hithighlightedproperties>
<HHUrl>http://SomeHardCodedString1/NewFolder1/SomeHardCodedString2</HHUrl>
</hithighlightedproperties>
<isdocument>True</isdocument>
<serverredirectedurl>http://SomeHardCodedString1/NewFolder1/SomeHardCodedString2
</serverredirectedurl>
</Result>
<Result>
<url>http://server/sites/sitecoll/library/NewFolder/test v1.0.docx</url>
<hithighlightedproperties>
<HHUrl>SomeValue1</HHUrl>
</hithighlightedproperties>
<isdocument>False</isdocument>
<serverredirectedurl>SomeValue1</serverredirectedurl>
</Result>
......
......
I have trimmed the original XML output to simplify the requirement and have a long complex XLST associated with the original XML. The goal is to modify the "HHUrl" string on the fly before it is rendered as HTML. For this particular requirement, I have created and embedded the following code, which works partially:
<xsl:template name="stripLast">
<xsl:param name="pText"/>
<xsl:param name="pDelim" select="'/'"/>
<xsl:if test="contains($pText, $pDelim)">
<xsl:value-of select="substring-before($pText, $pDelim)"/>
<xsl:if test="contains(substring-after($pText, $pDelim), $pDelim)">
<xsl:value-of select="$pDelim"/>
</xsl:if>
<xsl:call-template name="stripLast">
<xsl:with-param name="pText" select=
"substring-after($pText, $pDelim)"/>
<xsl:with-param name="pDelim" select="$pDelim"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="All_Results/Result/hithighlightedproperties/HHUrl">
<xsl:param name="staticUrl" select=" 'https://SomeHardCodedString1/' "/>
<xsl:copy>
<xsl:variable name="urlValue" select="string(.)"/>
<xsl:variable name="s" select="substring-after($urlValue, 'Portal/')"/>
<xsl:variable name="qsValue">
<xsl:call-template name="stripLast">
<xsl:with-param name="pText" select="$s"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat($staticUrl, $qsValue, 'SomeHardCodedString2')"/>
</xsl:copy>
</xsl:template>
Any help will be highly appreciated.
Thanks,
SharePointDev.
回答1:
I had a bit of a play around, the following idea might be useful. It will be a bit fragile though, if there are more than two levels in the bit you want to hard-code around (ie. "Folder/", "Folder/Folder1/", (and it breaks if), "Folder/Folder1/Folder2/"), but you could extend the idea:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//HHUrl[ancestor::Result[isdocument[.='True']]]">
<xsl:variable name="url" select="../../url"></xsl:variable>
<xsl:variable name="firsttoken" select="concat(substring-before(substring-after($url,'library/'),'/'),'/')"></xsl:variable>
<xsl:variable name="secondtoken" select="substring-before(substring-after($url,$firsttoken),'/')"></xsl:variable>
<xsl:variable name="thirdtoken" select="concat($firsttoken,$secondtoken)"></xsl:variable>
<HHUrl>http://SomeHardCodedString1/<xsl:if test="$secondtoken!=''"><xsl:value-of select="$thirdtoken"/></xsl:if><xsl:if test="$secondtoken=''"><xsl:value-of select="substring-before($firsttoken,'/')"/></xsl:if>/SomeHardCodedString2</HHUrl>
</xsl:template>
<xsl:template match="//serverredirectedurl[ancestor::Result[isdocument[.='True']]]">
<xsl:variable name="url" select="../url"></xsl:variable>
<xsl:variable name="firsttoken" select="concat(substring-before(substring-after($url,'library/'),'/'),'/')"></xsl:variable>
<xsl:variable name="secondtoken" select="substring-before(substring-after($url,$firsttoken),'/')"></xsl:variable>
<xsl:variable name="thirdtoken" select="concat($firsttoken,$secondtoken)"></xsl:variable>
<serverredirectedurl>http://SomeHardCodedString1/<xsl:if test="$secondtoken!=''"><xsl:value-of select="$thirdtoken"/></xsl:if><xsl:if test="$secondtoken=''"><xsl:value-of select="substring-before($firsttoken,'/')"/></xsl:if>/SomeHardCodedString2</serverredirectedurl>
</xsl:template>
来源:https://stackoverflow.com/questions/19008838/xslt-modifying-value-of-a-xml-node-depending-on-other-nodes