after getting hints here: xslt string replace concrete example,
I've made these two templates to use in my own environment.
They use html-tables in order to get some formatting done when calling the second template (fhb-bib-info) from yet another .xsl-template:
<xsl:template name="string-replace-all">
<xsl:param name="text" />
<xsl:param name="replace" />
<xsl:param name="by" />
<xsl:choose>
<xsl:when test="$text = '' or $replace = ''or not($replace)" >
<!-- Prevent this routine from hanging -->
<xsl:value-of select="$text" />
</xsl:when>
<xsl:when test="contains($text, $replace)">
<xsl:value-of select="substring-before($text,$replace)" />
<xsl:value-of select="$by" />
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)" />
<xsl:with-param name="replace" select="$replace" />
<xsl:with-param name="by" select="$by" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="fhb-bib-info">
<xsl:choose>
<xsl:when test="./bib-info =''">
<tr>
<td colspan="2"><xsl:text>Autor: </xsl:text><xsl:value-of select="./z13-author"/></td>
</tr>
<tr>
<td colspan="2"><xsl:text>Titel: </xsl:text><xsl:value-of select="./z13-title"/></td>
</tr>
<tr>
<td colspan="2"><xsl:text>ISBN/ISSN: </xsl:text><xsl:value-of select="./z13-isbn-issn"/></td>
</tr>
</xsl:when>
<xsl:otherwise>
<xsl:template match="bib-info">
<xsl:variable name="newtext">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="text()" />
<xsl:with-param name="replace" select="']: '" />
<xsl:with-param name="by" select="']: '" />
</xsl:call-template>
</xsl:variable>
</xsl:template>
<tr>
<td colspan="2"><bib-info><xsl:value-of select="$newtext" /></bib-info></td>
</tr>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
But when I try to run them I get the following errors. The two templates are part of the file funcs.xsl. Line 153 is where the xsl:value-of select="$newtext" statement occurs.
Can anybody help me debug/clear these error-messages? Kate
Error at xsl:value-of on line 153 of file:/C:/Aleph-22-Test/alephcom/files/SWF50/PrintTemplates/ger/funcs.xsl:
XPST0008: XPath syntax error at char 8 on line 153 in {$newtext}:
Variable $newtext has not been declared
Error at xsl:template on line 143 of file:/C:/Aleph-22-Test/alephcom/files/SWF50/PrintTemplates/ger/funcs.xsl:
XTSE0010: An xsl:otherwise element must not contain an xsl:template element
Error at xsl:template on line 143 of file:/C:/Aleph-22-Test/alephcom/files/SWF50/PrintTemplates/ger/funcs.xsl:
XTSE0010: Element must be used only at top level of stylesheet
With the help of a colleague I managed to solve my problem and debug my code so that my templates now work as wanted. The crucial flaw in my logic was that I expected to have to specifically display the bib-info-element after the replace-action. I found out that's not the case.
Another thing is the need for a recursiv call on the replace-action as only on blanc is being replaced instead of the whole bunch.
So here's the working code:
<xsl:template name="plain-fhb-bib-info">
<xsl:choose>
<xsl:when test="./bib-info =''">
<xsl:text>Autor: </xsl:text><xsl:value-of select="./z13-author"/><xsl:call-template name="new-line"/>
<xsl:text>Titel: </xsl:text><xsl:value-of select="./z13-title"/><xsl:call-template name="new-line"/>
<xsl:text>ISBN/ISSN: </xsl:text><xsl:value-of select="./z13-isbn-issn"/><xsl:call-template name="new-line"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="plain-string-replace-all-recursive">
<xsl:with-param name="text" select="./bib-info" />
<xsl:with-param name="replace" select="']: '" />
<xsl:with-param name="by" select="']: '" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- recursively applies plain-string-replace-all until there are no more matches -->
<xsl:template name="plain-string-replace-all-recursive">
<xsl:param name="text" />
<xsl:param name="replace" />
<xsl:param name="by" />
<xsl:choose>
<xsl:when test="contains($text, $replace)">
<xsl:variable name="newtext">
<xsl:call-template name="plain-string-replace-all">
<xsl:with-param name="text" select="$text" />
<xsl:with-param name="replace" select="$replace" />
<xsl:with-param name="by" select="$by" />
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="plain-string-replace-all-recursive">
<xsl:with-param name="text" select="$newtext" />
<xsl:with-param name="replace" select="$replace" />
<xsl:with-param name="by" select="$by" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="plain-string-replace-all">
<xsl:param name="text" />
<xsl:param name="replace" />
<xsl:param name="by" />
<xsl:choose>
<xsl:when test="$text = '' or $replace = ''or not($replace)" >
<xsl:value-of select="$text" />
</xsl:when>
<xsl:when test="contains($text, $replace)">
<xsl:value-of select="substring-before($text,$replace)" />
<xsl:value-of select="$by" />
<xsl:call-template name="plain-string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)" />
<xsl:with-param name="replace" select="$replace" />
<xsl:with-param name="by" select="$by" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Related
I am acting on a set of documents that have a <DataTypes> area, which defines the structure of groups of primative datatypes and other structures, and a <Tags> area, which defines the values of instances of these datatypes.
Original XML
<?xml version="1.0" encoding="utf-8" ?>
<Program>
<DataTypes>
<DataType Name="String20">
<Member Name="LEN" DataType="INTEGER" Dimension="0" />
<Member Name="DATA" DataType="BYTE" Dimension="20" />
</DataType>
<DataType Name="UDT_Params">
<Member Name="InAlarm" DataType="BIT" Dimension="0" />
<Member Name="SetPoint" DataType="FLOAT" Dimension="0" />
<Member Name="DwellTime" DataType="INTEGER" Dimension="0" />
<Member Name="UserName" DataType="String20" Dimension="0" />
</DataType>
</DataTypes>
<Tags>
<Tag Name="MyParameters" DataType="UDT_Params">
<Data Name="InAlarm" DataType="BIT" Value="0" />
<Data Name="SetPoint" DataType="FLOAT" Value="4.5" />
<Data Name="DwellTime" DataType="INTEGER" Value="10" />
<Data Name="UserName" DataType="String20">
<Data Name="LEN" DataType="INTEGER" Value="3" />
<Data Name="DATA" DataType="String20" > <!--The system I'm working in shows strings as arrays of BYTES in DataType, -->
Bob <!--but calls them out as Strings when they are used as tags. I cannot change it.-->
</Data>
</Data>
</Tag>
</Tags>
</Program>
Stylesheet
<?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:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<!--Packing algorithm. Works fine on datatypes, but not on Tags.-->
<xsl:template name="pack-nodes">
<xsl:param name="nodes" />
<!--Omitted for brevity-->
</xsl:template>
<!--Pack DataTypes-->
<xsl:variable name="datatypes-packed">
<xsl:call-template name="pack-nodes">
<xsl:with-param name="nodes" select="/Program/DataTypes/DataType" />
</xsl:call-template>
</xsl:variable>
<!--Write DataTypes to output.-->
<xsl:template match="/Program/DataTypes">
<xsl:copy>
<xsl:for-each select="msxsl:node-set($datatypes-packed)">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<!--Pack tags-->
<xsl:variable name="tags-packed">
<xsl:call-template name="pack-nodes">
<xsl:with-param name="nodes" select="/Program/Tags/Tag" />
</xsl:call-template>
</xsl:variable>
<!--Write Tags to output.-->
<xsl:template match="/Program/Tags">
<xsl:copy>
<xsl:for-each select="msxsl:node-set($tags-packed)">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="utf-8"?>
<Program>
<DataTypes>
<DataType Name="String20">
<Member Name="LEN" DataType="INTEGER" Dimension="0"/>
<Member Name="DATA" DataType="BYTE" Dimension="20"/>
</DataType>
<DataType Name="Parameters" DataType="UDT_Params">
<Member Name="UserName" DataType="String20" Dimension="0"/>
<Member Name="SetPoint" DataType="FLOAT" Dimension="0"/>
<Member Name="DwellTime" DataType="INTEGER" Dimension="0"/>
<Member Name="InAlarm" DataType="BIT" Dimension="0"/>
</DataType>
</DataTypes>
<Tags>
<Tag Name="MyParameters" DataType="UDT_Params">
<Data Name="UserName" DataType="String20">
<Data Name="DATA" DataType="String20"> <!--Note that DATA comes before LEN -->
Bob
</Data>
<Data Name="LEN" DataType="INTEGER" Value="3"/>
</Data>
<Data Name="SetPoint" DataType="FLOAT" Value="4.5"/>
<Data Name="DwellTime" DataType="INTEGER" Value="10"/>
<Data Name="InAlarm" DataType="BIT" Value="0"/>
</Tag>
</Tags>
</Program>
My operations on the DataTypes section adds nodes and changes the node order. For the section to work correctly, the tag elements must match the contents and order of their respective datatypes, exactly.
If I keep a variable in memory of the final state of the DataSet nodes, is there a simple way to have the tag nodes look up their dataset (via the Structure and StructureMember #DataSet attributes, and sort their members accordingly?
I'm having trouble figuring out where to start.
NOTE: Transformation must be in XSLT 1.0. I'm using .Net, and don't want to introduce a lot of dependencies on external libraries.
It's a bit tricky in XSLT 1.0 (isn't everything?) but a technique that sometimes works is to construct a variable $tokens containing the list of tokens in the required order, for example "|Description|Name|ProcessEntityIndex|Severity|...", and then sort on select="string-length(substring-before($tokens, concat('|',#Name)))".
Using Michael Kay's suggesting for sorting, I ended up with the following:
Stylesheet
<?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"/>
<!--Skipped to new part -->
<xsl:template name="sort-by-datatype">
<xsl:param name="tags" />
<xsl:param name="datatypes" />
<xsl:for-each select="msxsl:node-set($tags)">
<!--First, do an edge-check.-->
<xsl:variable name="edge">
<xsl:call-template name="edge-check">
<xsl:with-param name="n1" select="." />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<!--No children, nothing to sort. Just do a deep copy.-->
<xsl:when test="$edge = 'true'">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<!--Search for datatype in the DataTypes nodeset, and use it to create a list of members in order.-->
<xsl:variable name="tag-datatype" select="./#DataType" />
<xsl:variable name="tokens-untrimmed">
<xsl:for-each select="msxsl:node-set($datatypes)/DataType[#Name = $tag-datatype]/Member">
<xsl:value-of select="concat(' | ', #Name)"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="tokens" select="substring-after($tokens-untrimmed, '|')" />
<xsl:choose>
<!--If tokens string is empty (maybe because we couldn't find the datatype?), just copy the tag as it is, then recurse.-->
<xsl:when test="string-length($tokens) = 0">
<xsl:copy>
<xsl:copy-of select="#*"/>
<xsl:call-template name="sort-by-datatype">
<xsl:with-param name="tags" select="." />
<xsl:with-param name="datatypes" select="$datatypes" />
</xsl:call-template>
</xsl:copy>
</xsl:when>
<!--Otherwise, sort members in the same order as datatype-->
<xsl:otherwise>
<!--Build variable with sorted members.-->
<xsl:variable name="tag-members-sorted">
<xsl:for-each select="*">
<xsl:sort data-type="number" order="ascending" select="string-length(substring-before($tokens, concat(' | ', #Name)))" /> <!--Magic Sort Algorithm-->-->
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<!--Copy the parent node node.-->
<xsl:copy>
<xsl:copy-of select="#*"/>
<!--Now sort and copy the children.-->
<xsl:for-each select="msxsl:node-set($tag-members-sorted)/*">
<!--Recurse. This copies the child node.-->
<xsl:call-template name="sort-by-datatype">
<xsl:with-param name="tags" select="." />
<xsl:with-param name="datatypes" select="$datatypes" />
</xsl:call-template>
</xsl:for-each>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<!--Pack tags-->
<xsl:variable name="tags-packed">
<xsl:call-template name="sort-by-datatype">
<xsl:with-param name="tags" select="/Program/Tags/Tag" />
<xsl:with-param name="datatypes" select="$datatypes-packed" />
</xsl:call-template>
</xsl:variable>
<!--Skipped for brevity-->
</xsl:stylesheet>
I am able to parse xml to json by
http://www.armbruster-it.org/index.php/12-it/pl-sql/12-oracle-xml-and-json-goodies
But when any CDATA come it fail . Can you tell me the rule of xslt so that i can copy all data that is written in CDATA as it is in json .
> select
> packagename.itstar_xml_util.xml2json(xmltype('<ArticleDetail><![CDATA[<P
> class=MsoNormal style="MARGIN: 0in 0in 0pt"></P>]]></ArticleDetail>'))
> FROM DUAL;
This is data
<ArticleDetail><![CDATA[<P class=MsoNormal style="MARGIN: 0in 0in 0pt"></P>]]></ArticleDetail>
The xslt is
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="no" omit-xml-declaration="yes" method="text" encoding="UTF-8" media-type="text/x-json"/>
<xsl:strip-space elements="*"/>
<!--contant-->
<xsl:variable name="d">0123456789</xsl:variable>
<!-- ignore document text -->
<xsl:template match="text()[preceding-sibling::node() or following-sibling::node()]"/>
<!-- string -->
<xsl:template match="text()">
<xsl:call-template name="escape-string">
<xsl:with-param name="s" select="."/>
</xsl:call-template>
</xsl:template>
<!-- Main template for escaping strings; used by above template and for object-properties
Responsibilities: placed quotes around string, and chain up to next filter, escape-bs-string -->
<xsl:template name="escape-string">
<xsl:param name="s"/>
<xsl:text>"</xsl:text>
<xsl:call-template name="escape-bs-string">
<xsl:with-param name="s" select="$s"/>
</xsl:call-template>
<xsl:text>"</xsl:text>
</xsl:template>
<!-- Escape the backslash (\) before everything else. -->
<xsl:template name="escape-bs-string">
<xsl:param name="s"/>
<xsl:choose>
<xsl:when test="contains($s,''\'')">
<xsl:call-template name="escape-quot-string">
<xsl:with-param name="s" select="concat(substring-before($s,''\''),''\\'')"/>
</xsl:call-template>
<xsl:call-template name="escape-bs-string">
<xsl:with-param name="s" select="substring-after($s,''\'')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="escape-quot-string">
<xsl:with-param name="s" select="$s"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Escape the double quote ("). -->
<xsl:template name="escape-quot-string">
<xsl:param name="s"/>
<xsl:choose>
<xsl:when test="contains($s,'';'')">
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="concat(substring-before($s,'';''),''"'')"/>
</xsl:call-template>
<xsl:call-template name="escape-quot-string">
<xsl:with-param name="s" select="substring-after($s,'';'')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="$s"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Replace tab, line feed and/or carriage return by its matching escape code. Can''t escape backslash
or double quote here, because they don''t replace characters (; becomes \t), but they prefix
characters (\ becomes \\). Besides, backslash should be seperate anyway, because it should be
processed first. This function can''t do that. -->
<xsl:template name="encode-string">
<xsl:param name="s"/>
<xsl:choose>
<!-- tab -->
<xsl:when test="contains($s,'';'')">
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="concat(substring-before($s,'';''),''\t'',substring-after($s,'';''))"/>
</xsl:call-template>
</xsl:when>
<!-- line feed -->
<xsl:when test="contains($s,'';'')">
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="concat(substring-before($s,'';''),''\n'',substring-after($s,'';''))"/>
</xsl:call-template>
</xsl:when>
<!-- carriage return -->
<xsl:when test="contains($s,'';'')">
<xsl:call-template name="encode-string">
<xsl:with-param name="s" select="concat(substring-before($s,'';''),''\r'',substring-after($s,'';''))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$s"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- number (no support for javascript mantise) -->
<xsl:template match="text()[not(string(number())=''NaN'')]">
<xsl:value-of select="."/>
</xsl:template>
<!-- boolean, case-insensitive -->
<xsl:template match="text()[translate(.,''TRUE'',''true'')=''true'']">true</xsl:template>
<xsl:template match="text()[translate(.,''FALSE'',''false'')=''false'']">false</xsl:template>
<!-- item:null -->
<xsl:template match="*[count(child::node())=0]">
<xsl:call-template name="escape-string">
<xsl:with-param name="s" select="local-name()"/>
</xsl:call-template>
<xsl:text>:null</xsl:text>
<xsl:if test="following-sibling::*">,</xsl:if>
<xsl:if test="not(following-sibling::*)">}</xsl:if> <!-- MBR 30.01.2010: added this line as it appeared to be missing from stylesheet -->
</xsl:template>
<!-- object -->
<xsl:template match="*" name="base">
<xsl:if test="not(preceding-sibling::*)">{</xsl:if>
<xsl:call-template name="escape-string">
<xsl:with-param name="s" select="name()"/>
</xsl:call-template>
<xsl:text>:</xsl:text>
<xsl:apply-templates select="child::node()"/>
<xsl:if test="following-sibling::*">,</xsl:if>
<xsl:if test="not(following-sibling::*)">}</xsl:if>
</xsl:template>
<!-- array -->
<xsl:template match="*[count(../*[name(../*)=name(.)])=count(../*) and count(../*)>1]">
<xsl:if test="not(preceding-sibling::*)">[</xsl:if>
<xsl:choose>
<xsl:when test="not(child::node())">
<xsl:text>null</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="child::node()"/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="following-sibling::*">,</xsl:if>
<xsl:if test="not(following-sibling::*)">]</xsl:if>
</xsl:template>
<!-- convert root element to an anonymous container -->
<xsl:template match="/">
<xsl:apply-templates select="node()"/>
</xsl:template>
</xsl:stylesheet>
In Microsoft Dynamics GP I need to set the tax on individual orders as taxable/non-taxable (cannot be done on customer record).
For some reason no matter what I pass into the CreateSalesOrder call for the web services, it will not save the tax information.
I've tried:
Using the CreateSalesInvoice policy which has had "Create Taxes Behavior" set to "Taxes will be provided"
Overrode policies using "Use Header Level Taxes Behavior" and "Create Taxes Behavior" all 4 modes have been tried.
Provided taxes as a total on the Sales Order
Provided taxes as a tax detail on the sales order
Provided taxes as a total on the line item
Provided taxes as a tax detail on the sales order
Set the TaxScheduleKey on the order
Set the TaxScheduleKey on the line items
Taxes just get blanked out in GP, it's infuriating... Any ideas? I do have access to the Dynamics database but I'd really rather not go that route if possible.
My research has led me to believe that this is broken (every thread on this subject ends with no answers) and Microsoft isn't going to fix it, but that really hurts automation something awful.
Ran into this issue today. A little background:
After trying everything outlined above, modifying policies - particularly, Sales Document - Create Sales Document policies, and becoming frustrated at there being no policies for Create Sales Order to allow taxes to be specified, I came across this MSDN article about how the GP Services could be designed or extended: https://msdn.microsoft.com/en-us/library/dd996499.aspx
Not interested in going quite that far, I found - "Program Files\Microsoft Dynamics\GPWebServices\XSLT", in particular, the "Microsoft.Dynamics.GP.SalesOrderCreate.xslt" file.
As it comes installed with GreatPlains, there are no transforms in place to utilize incoming tax data at all (no surprise, given what had been tried). USINGHEADERLEVELTAXES is set to 0.
Combining the Tax lines from the "Microsoft.Dynamics.GP.SalesInvoiceCreate.xslt" file into the SalesOrderCreate.xslt file, you can modify the XML sent into eConnect for SalesOrderCreate to properly create the Taxes.
The below example uses/was tested for header level tax behavior.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mbs="http://schemas.microsoft.com/dynamics/2006/01"
xmlns:gputil="urn:Microsoft.Dynamics.GP.TransformUtilities"
version="1.0">
<xsl:import href="Microsoft.Dynamics.GP.SalesCreateUpdateLibrary.xslt"/>
<xsl:import href="Microsoft.Dynamics.GP.StandardLibrary.xslt"/>
<xsl:variable name="CompanyId">
<xsl:value-of select="/SalesOrder/mbs:Context/mbs:OrganizationKey/mbs:Id"/>
</xsl:variable>
<xsl:template match ="/">
<eConnect xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:apply-templates />
</eConnect>
</xsl:template>
<xsl:template match="SalesOrder">
<SOPTransactionType>
<xsl:apply-templates select="Lines/SalesOrderLine/Serials/SalesLineSerial">
<xsl:with-param name="UpdateIfExists">0</xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="Lines/SalesOrderLine/Components/SalesOrderComponent/Serials/SalesComponentSerial">
<xsl:with-param name="UpdateIfExists">0</xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="Lines/SalesOrderLine/Lots/SalesLineLot">
<xsl:with-param name="UpdateIfExists">0</xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="Lines/SalesOrderLine/Components/SalesOrderComponent/Lots/SalesComponentLot">
<xsl:with-param name="UpdateIfExists">0</xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="Lines/SalesOrderLine" />
<xsl:apply-templates select="Lines/SalesOrderLine/Components/SalesOrderComponent" />
<xsl:apply-templates select="TrackingNumbers/SalesTrackingNumber" />
<xsl:apply-templates select="Taxes/SalesDocumentTax" />
<xsl:apply-templates select="Commissions/SalesCommission" />
<xsl:apply-templates select="Payments/SalesPayment">
<xsl:with-param name="UpdateIfExists">0</xsl:with-param>
</xsl:apply-templates>
<xsl:apply-templates select="UserDefined" />
<xsl:apply-templates select="Lines/SalesOrderLine/Bins/SalesLineBin" />
<xsl:apply-templates select="Lines/SalesOrderLine/Components/SalesOrderComponent/Bins/SalesComponentBin" />
<xsl:call-template name="SalesHeader" />
<xsl:apply-templates select="ProcessHolds/SalesProcessHold">
<xsl:with-param name="UpdateIfExists">0</xsl:with-param>
</xsl:apply-templates>
</SOPTransactionType>
</xsl:template>
<xsl:template match="SalesOrderLine">
<taSopLineIvcInsert>
<xsl:call-template name="CreateUpdateLine">
<xsl:with-param name="UpdateIfExists">0</xsl:with-param>
<xsl:with-param name="CompanyId">
<xsl:value-of select="$CompanyId" />
</xsl:with-param>
</xsl:call-template>
<xsl:if test="QuantityToBackorder/Value != ''">
<QTYTBAOR>
<xsl:value-of select="QuantityToBackorder/Value" />
</QTYTBAOR>
</xsl:if>
<xsl:if test="QuantityToInvoice/Value != ''">
<QUANTITY>
<xsl:value-of select="QuantityToInvoice/Value" />
</QUANTITY>
</xsl:if>
<xsl:if test="QuantityCanceled/Value != ''">
<QTYCANCE>
<xsl:value-of select="QuantityCanceled/Value" />
</QTYCANCE>
</xsl:if>
<xsl:if test="QuantityFulfilled/Value != ''">
<QTYFULFI>
<xsl:value-of select="QuantityFulfilled/Value" />
</QTYFULFI>
</xsl:if>
<xsl:if test="TaxAmount/Value != ''">
<TAXAMNT>
<xsl:value-of select="TaxAmount/Value" />
</TAXAMNT>
</xsl:if>
<RecreateDist>0</RecreateDist>
</taSopLineIvcInsert>
</xsl:template>
<xsl:template match="SalesOrderComponent">
<taSopLineIvcInsertComponent>
<xsl:call-template name="CreateUpdateComponent">
<xsl:with-param name="UpdateIfExists">0</xsl:with-param>
</xsl:call-template>
<xsl:if test="QuantityToBackorder/Value != ''">
<QTYTBAOR>
<xsl:value-of select="QuantityToBackorder/Value" />
</QTYTBAOR>
</xsl:if>
<xsl:if test="QuantityToInvoice/Value != ''">
<QUANTITY>
<xsl:value-of select="QuantityToInvoice/Value" />
</QUANTITY>
</xsl:if>
<xsl:if test="QuantityCanceled/Value != ''">
<QTYCANCE>
<xsl:value-of select="QuantityCanceled/Value" />
</QTYCANCE>
</xsl:if>
<xsl:if test="QuantityFulfilled/Value != ''">
<QTYFULFI>
<xsl:value-of select="QuantityFulfilled/Value" />
</QTYFULFI>
</xsl:if>
</taSopLineIvcInsertComponent>
</xsl:template>
<xsl:template name="SalesHeader">
<taSopHdrIvcInsert>
<xsl:call-template name="CreateUpdateDocument">
<xsl:with-param name="UpdateIfExists">0</xsl:with-param>
<xsl:with-param name="CompanyId">
<xsl:value-of select="$CompanyId" />
</xsl:with-param>
</xsl:call-template>
<xsl:if test="PaymentAmount/Value != ''">
<PYMTRCVD>
<xsl:value-of select="PaymentAmount/Value" />
</PYMTRCVD>
</xsl:if>
<xsl:if test="TaxAmount/Value != ''">
<TAXAMNT>
<xsl:value-of select="TaxAmount/Value" />
</TAXAMNT>
</xsl:if>
<USINGHEADERLEVELTAXES>1</USINGHEADERLEVELTAXES>
<CREATEDIST>0</CREATEDIST>
<CREATETAXES>0</CREATETAXES>
</taSopHdrIvcInsert>
</xsl:template>
</xsl:stylesheet>
I'm trying to make a custom filter which sorts on authors (users) in the SharePoint 2013 blog. I'm working with XSL dataview and it's exported to a web part. I have a column called Author which gets the information from Created By. When I click on a user in the web part it shows all posts instead of the selected author. The URL is mysite/default.aspx?Author=FirstName LastName".
Code (default.aspx):
<xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">
<xsl:call-template name="dvt_1"/>
</xsl:template>
<xsl:template name="dvt_1">
<xsl:variable name="dvt_StyleName">RepForm3</xsl:variable>
<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row[not(#Author.title=preceding-sibling::Row/#Author.title)]" />
<xsl:call-template name="dvt_1.header">
<xsl:with-param name="Rows" select="$Rows" />
</xsl:call-template>
<div class="blogRefineByAuthorContainer">
<xsl:call-template name="dvt_1.body">
<xsl:with-param name="Rows" select="$Rows"/>
</xsl:call-template>
</div>
</xsl:template>
<xsl:template name="dvt_1.header">
<xsl:param name="Rows" />
<div class="blogRefineByAuthorEveryAuthor">Everyone</div>
</xsl:template>
<xsl:template name="dvt_1.body">
<xsl:param name="Rows"/>
<xsl:for-each select="$Rows">
<xsl:call-template name="dvt_1.rowview" />
</xsl:for-each>
</xsl:template>
<xsl:template name="dvt_1.rowview">
<div class="blogRefineByAuthorAuthorTitle">
<xsl:value-of select="#Author.title" />
</div>
</xsl:template>
Any ideas of what it could be? Between the first and last name there is a space in the URL, but I don't think it makes any sense. I have tried with %20 without any result.
I don't see the solution and hope someone can help me. I want to sort the result by title. But I don't know where and how to put the sort into the XSL file.
Can somebody help me?
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="TotalResults" />
<xsl:template match="NumberOfResults" />
<xsl:template name="DisplayString">
<xsl:param name="str" />
<xsl:if test='string-length($str) > 0'>
<xsl:value-of select="$str" />
</xsl:if>
</xsl:template>
<xsl:template name="HitHighlighting">
<xsl:param name="hh" />
<xsl:apply-templates select="$hh"/>
</xsl:template>
<xsl:template name="ResultPreviewToolTip">
<xsl:param name="contentclass" />
<xsl:param name="picturethumbnailurl" />
<xsl:param name="url" />
<xsl:param name="title" />
<xsl:param name="hithighlightedsummary" />
<xsl:param name="description" />
<xsl:param name="version" />
<xsl:choose>
<xsl:when test="$contentclass[. = 'STS_ListItem_PictureLibrary'] and $picturethumbnailurl[. != '']">
<div>
<a href="{$url}" title="{$title}">
<img src="{$picturethumbnailurl}" alt="" />
</a>
</div>
</xsl:when>
<xsl:when test="contains( $url, 'jpg' ) or contains( $url, 'jpeg' ) or contains( $url, 'gif' ) or contains( $url, 'JPG' ) or contains( $url, 'JPEG' ) or contains( $url, 'GIF' )">
<div>
<img src="/_layouts/AssetUploader.aspx?Size=Medium&ImageUrl={$url}" alt="" />
</div>
</xsl:when>
<xsl:otherwise>
<div>
<xsl:choose>
<xsl:when test="$hithighlightedsummary[. != '']">
<b>Preview:</b>
<br/>
<xsl:call-template name="HitHighlighting">
<xsl:with-param name="hh" select="$hithighlightedsummary" />
</xsl:call-template>
</xsl:when>
<xsl:when test="$description[. != '']">
<b>Preview:</b>
<br/>
<xsl:value-of select="$description"/>
</xsl:when>
<xsl:otherwise>
No preview available
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="DisplayString">
<xsl:with-param name="str" select="$version" />
<xsl:with-param name="text" select="'Version: '" />
<xsl:with-param name="stringcolor" select="'#808080'" />
</xsl:call-template>
</div >
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="Result">
<xsl:variable name="tdClass">
<xsl:if test="(position() mod 2 = 0)">
<xsl:value-of select="'even'" />
</xsl:if>
<xsl:if test="(position() mod 2 = 1)">
<xsl:value-of select="'odd'" />
</xsl:if>
</xsl:variable>
<tr>
<td class="{$tdClass}">
<a href="#" class="tooltip">
<img>
<xsl:attribute name="src">
<xsl:value-of select="imageurl"/>
</xsl:attribute>
</img>
<span>
<xsl:call-template name="ResultPreviewToolTip">
<xsl:with-param name="contentclass" select="contentclass" />
<xsl:with-param name="description" select="description" />
<xsl:with-param name="hithighlightedsummary" select="hithighlightedsummary" />
<xsl:with-param name="picturethumbnailurl" select="picturethumbnailurl" />
<xsl:with-param name="title" select="title" />
<xsl:with-param name="url" select="url" />
<xsl:with-param name="version" select="version" />
</xsl:call-template>
</span>
</a>
</td>
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="url" disable-output-escaping="yes" />
</xsl:attribute>
<xsl:value-of select="filename"/>
</a>
</td>
<td class="{$tdClass}">
<a>
<xsl:attribute name="href">
<xsl:value-of select="url" disable-output-escaping="yes" />
</xsl:attribute>
<xsl:choose>
<xsl:when test="doctitle != ''">
<xsl:value-of select="doctitle"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="title"/>
</xsl:otherwise>
</xsl:choose>
</a>
</td>
<td class="{$tdClass}">
<xsl:choose>
<xsl:when test="docauthor != ''">
<xsl:value-of select="docauthor"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="author"/>
</xsl:otherwise>
</xsl:choose>
</td>
<td class="{$tdClass}">
<xsl:value-of select="revisiondate" />
</td>
<td class="{$tdClass}">
<xsl:value-of select="doclanguage"/>
</td>
<td class="{$tdClass}">
<a>
<xsl:attribute name="href">
<xsl:value-of select="sitename" disable-output-escaping="yes" />
</xsl:attribute>
<img src="/_layouts/images/breadcrumbbutton.png" style="border-style: none" />
</a>
<xsl:call-template name="ShowVersionHistory" />
</td>
</tr>
</xsl:template>
<xsl:template name="ShowVersionHistory">
<!-- First, encode Url -->
<xsl:variable name="EncodedUrl">
<xsl:value-of disable-output-escaping="yes" select="ddwrt:UrlEncode(url)" />
</xsl:variable>
<!-- does only work for office docuemnts -->
<xsl:if test="string-length(serverredirectedurl) > 0">
<!-- get web url from office web app link -->
<xsl:variable name="WebUrl">
<xsl:value-of select="substring-before(serverredirectedurl, '_layouts')"/>
</xsl:variable>
<!-- create link -->
<xsl:variable name="FinalLink">
<xsl:value-of select="$WebUrl"/>
<xsl:text>_layouts/Versions.aspx?FileName=</xsl:text>
<xsl:value-of select="$EncodedUrl"/>
</xsl:variable>
<a href="{$FinalLink}" target="_blank" Title="Version History">
<img src="/_layouts/images/versions.gif" style="border-style: none" />
</a>
</xsl:if>
</xsl:template>
<xsl:template match="/">
<table class="searchresult">
<tr>
<th width="18"></th>
<th>Filename</th>
<th>Title</th>
<th>Author</th>
<th>Revision Date</th>
<th>Language</th>
<th>Actions</th>
</tr>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="TotalResults" />
<xsl:template match="NumberOfResults" />
<xsl:template name="DisplayString">
<xsl:param name="str" />
<xsl:if test='string-length($str) > 0'>
<xsl:value-of select="$str" />
</xsl:if>
</xsl:template>
<xsl:template name="HitHighlighting">
<xsl:param name="hh" />
<xsl:apply-templates select="$hh"/>
</xsl:template>
<xsl:template name="ResultPreviewToolTip">
<xsl:param name="contentclass" />
<xsl:param name="picturethumbnailurl" />
<xsl:param name="url" />
<xsl:param name="title" />
<xsl:param name="hithighlightedsummary" />
<xsl:param name="description" />
<xsl:param name="version" />
<xsl:choose>
<xsl:when test="$contentclass[. = 'STS_ListItem_PictureLibrary'] and $picturethumbnailurl[. != '']">
<div>
<a href="{$url}" title="{$title}">
<img src="{$picturethumbnailurl}" alt="" />
</a>
</div>
</xsl:when>
<xsl:when test="contains( $url, 'jpg' ) or contains( $url, 'jpeg' ) or contains( $url, 'gif' ) or contains( $url, 'JPG' ) or contains( $url, 'JPEG' ) or contains( $url, 'GIF' )">
<div>
<img src="/_layouts/AssetUploader.aspx?Size=Medium&ImageUrl={$url}" alt="" />
</div>
</xsl:when>
<xsl:otherwise>
<div>
<xsl:choose>
<xsl:when test="$hithighlightedsummary[. != '']">
<b>Preview:</b>
<br/>
<xsl:call-template name="HitHighlighting">
<xsl:with-param name="hh" select="$hithighlightedsummary" />
</xsl:call-template>
</xsl:when>
<xsl:when test="$description[. != '']">
<b>Preview:</b>
<br/>
<xsl:value-of select="$description"/>
</xsl:when>
<xsl:otherwise>
No preview available
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="DisplayString">
<xsl:with-param name="str" select="$version" />
<xsl:with-param name="text" select="'Version: '" />
<xsl:with-param name="stringcolor" select="'#808080'" />
</xsl:call-template>
</div >
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="Result">
<xsl:variable name="tdClass">
<xsl:if test="(position() mod 2 = 0)">
<xsl:value-of select="'even'" />
</xsl:if>
<xsl:if test="(position() mod 2 = 1)">
<xsl:value-of select="'odd'" />
</xsl:if>
</xsl:variable>
<tr>
<td class="{$tdClass}">
<a href="#" class="tooltip">
<img>
<xsl:attribute name="src">
<xsl:value-of select="imageurl"/>
</xsl:attribute>
</img>
<span>
<xsl:call-template name="ResultPreviewToolTip">
<xsl:with-param name="contentclass" select="contentclass" />
<xsl:with-param name="description" select="description" />
<xsl:with-param name="hithighlightedsummary" select="hithighlightedsummary" />
<xsl:with-param name="picturethumbnailurl" select="picturethumbnailurl" />
<xsl:with-param name="title" select="title" />
<xsl:with-param name="url" select="url" />
<xsl:with-param name="version" select="version" />
</xsl:call-template>
</span>
</a>
</td>
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="url" disable-output-escaping="yes" />
</xsl:attribute>
<xsl:value-of select="filename"/>
</a>
</td>
<td class="{$tdClass}">
<a>
<xsl:attribute name="href">
<xsl:value-of select="url" disable-output-escaping="yes" />
</xsl:attribute>
<xsl:choose>
<xsl:when test="doctitle != ''">
<xsl:value-of select="doctitle"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="title"/>
</xsl:otherwise>
</xsl:choose>
</a>
</td>
<td class="{$tdClass}">
<xsl:choose>
<xsl:when test="docauthor != ''">
<xsl:value-of select="docauthor"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="author"/>
</xsl:otherwise>
</xsl:choose>
</td>
<td class="{$tdClass}">
<xsl:value-of select="revisiondate" />
</td>
<td class="{$tdClass}">
<xsl:value-of select="doclanguage"/>
</td>
<td class="{$tdClass}">
<a>
<xsl:attribute name="href">
<xsl:value-of select="sitename" disable-output-escaping="yes" />
</xsl:attribute>
<img src="/_layouts/images/breadcrumbbutton.png" style="border-style: none" />
</a>
<xsl:call-template name="ShowVersionHistory" />
</td>
</tr>
</xsl:template>
<xsl:template name="ShowVersionHistory">
<!-- First, encode Url -->
<xsl:variable name="EncodedUrl">
<xsl:value-of disable-output-escaping="yes" select="ddwrt:UrlEncode(url)" />
</xsl:variable>
<!-- does only work for office docuemnts -->
<xsl:if test="string-length(serverredirectedurl) > 0">
<!-- get web url from office web app link -->
<xsl:variable name="WebUrl">
<xsl:value-of select="substring-before(serverredirectedurl, '_layouts')"/>
</xsl:variable>
<!-- create link -->
<xsl:variable name="FinalLink">
<xsl:value-of select="$WebUrl"/>
<xsl:text>_layouts/Versions.aspx?FileName=</xsl:text>
<xsl:value-of select="$EncodedUrl"/>
</xsl:variable>
<a href="{$FinalLink}" target="_blank" Title="Version History">
<img src="/_layouts/images/versions.gif" style="border-style: none" />
</a>
</xsl:if>
</xsl:template>
<xsl:template match="/">
<table class="searchresult">
<tr>
<th width="18"></th>
<th>Filename</th>
<th>Title</th>
<th>Author</th>
<th>Revision Date</th>
<th>Language</th>
<th>Actions</th>
</tr>
<xsl:apply-templates />
</table>
</xsl:template>
</xsl:stylesheet>
You have to add <xsl:sort> (see: w3schools: xsl:sort Element).
It should be added to your xsl:apply-templates element (or if you would use xsl:for-each, then there).