我需要更改以下条件。目前,它可以查看整个xml并打印唯一的类。但我想要的标准是,它不是在整个xml中查找相同的类,而是检查以前的类是否与当前类相同。如果以前的课程不同,则将其视为新课程。 目前xslt正在基于xml中的唯一类创建表(请参阅xml)。 例如,如果xml有类 一个 乙 乙 甲
它只创建两个表。一个表用于A类,有两个记录,一个表有B类,有2个记录。但我是三张桌子。 A类的第一个表有一个记录(因为下一个类是不同的),B类的下一个表有2个记录(因为B有两个记录顺序)然后是A类的下一个表有一个记录(因为前一个记录属于类B)。所以简而言之,表创建的顺序应该像A类,B类,A类一样发生。 这是xslt。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:DBE="http://www.sdrc.com/metaphase/cf11bd">
<!-- Input Parameters -->
<xsl:param name="reportDate"/>
<xsl:param name="reportTitle"/>
<xsl:param name="reportLocale"/>
<xsl:param name="thinClientURLPrefix"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="baseUrl" select="'FIXME'"/>
<!-- Specify TextBundle file to read text entries from -->
<xsl:variable name="textBundleURI" select="'tc50_default_TextBundle.xml'"/>
<xsl:variable name="defaultTextBundleRoot" select="document($textBundleURI)"/>
<!--*************************************************************************-->
<!--*** Template for the Root of the XML Report document ********************-->
<!--*************************************************************************-->
<xsl:template match="/">
<HTML>
<HEAD>
<TITLE>
<xsl:value-of select="$reportTitle"/>
</TITLE>
</HEAD>
<BODY>
<CENTER>
<FONT>
</FONT>
</CENTER>
<BR/>
<TABLE border="0" align="center" width="90%">
<TR>
<TD width="95%">
<xsl:value-of select="$reportTitle"/>
</TD>
<TD>
<xsl:value-of select="$reportDate"/>
</TD>
</TR>
</TABLE>
<BR/>
<xsl:choose>
<xsl:when test="count(/DBE:ObjectSetRoot/DBE:Object) > 0">
<xsl:apply-templates mode="print_unique_classes"
select="/DBE:ObjectSetRoot/DBE:Object
[not(./@Class=preceding-sibling::DBE:Object/@Class)]"/>
</xsl:when>
<xsl:otherwise>
<CENTER><B>
<xsl:call-template name="GetTextFromBundle">
<xsl:with-param name="textID" select="'NO_ITEMS_FOUND'"/>
</xsl:call-template>
</B></CENTER>
</xsl:otherwise>
</xsl:choose>
<TABLE border="0">
<form name="myForm">
<tr>
<th><input name="Print" type="button" value="Print" onclick="javascript:window.print()" style="font: bold 12px Arial;background-color:transparent"/>
</th>
<th><input type="button" value="Save" onclick="document.execCommand('SaveAs', true)" style="font: bold 12px Arial;background-color:transparent"/>
</th>
</tr>
</form>
</TABLE>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="DBE:Object" mode="print_unique_classes">
<xsl:variable name="className" select="./DBE:Attribute[@name='Class']/DBE:Translation"/>
<TABLE>
<TR>
<TD bgcolor="#C3E1FF" >
<xsl:value-of select="$className"/>
</TD>
<xsl:variable name="classNameAct" select="./DBE:Attribute[@name='Class']/DBE:String"/>
<xsl:if test="$classNameAct = 'x0EcnPrd' or $classNameAct = 'x0EcnNSR' or $classNameAct = 'x0EcnSR' or $classNameAct = 'x0EcnSOP'">
<TD>  :     </TD>
<TD bgcolor="#FF7979" >
<xsl:variable name="changeid" select="./DBE:Attribute[@name='x0ChangeId']/DBE:String"/>
<xsl:value-of select="$changeid"/>
</TD>
</xsl:if>
</TR>
</TABLE>
<xsl:apply-templates mode="print_item_class" select="." />
<br/>
<br/>
</xsl:template>
<xsl:template mode="print_item_class" match="DBE:Object">
<xsl:variable name="className" select="./@Class"/>
<TABLE border="1" align="center" width="90%">
<TR>
<xsl:apply-templates mode="print_table_column_names" select="./DBE:Attribute" />
</TR>
<xsl:apply-templates mode="print_similar_item_classes"
select="/DBE:ObjectSetRoot/DBE:Object[@Class=$className]"/>
</TABLE>
</xsl:template>
<xsl:template mode="print_table_column_names" match="DBE:Object/DBE:Attribute">
<xsl:variable name="columnName" select="./@name"/>
<xsl:if test="not(contains($columnName, 'OBID'))" >
<xsl:if test="not(contains($columnName, 'Class'))" >
<xsl:if test="not($columnName = 'Left' or $columnName = 'LeftMember')">
<xsl:if test="not($columnName = 'Right' or $columnName = 'RightMember')">
<xsl:if test="not($columnName = 'NavTplName' or $columnName = 'CustTplMsgName' or $columnName = 'CustTplMsgClassName' or $columnName = 'CustTplDialogName')">
<xsl:if test="not($columnName = 'XrfItemHandle')">
<TH bgcolor="#C0C0C0">
<xsl:variable name="columnDisplayName" select="./@displayAs"/>
<xsl:value-of select="$columnDisplayName"/>
</TH>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template mode="print_similar_item_classes" match="DBE:Object">
<TR>
<xsl:variable name="xrfItemHandle" select="./DBE:Attribute[@name='XrfItemHandle']/DBE:String"/>
<xsl:apply-templates mode="print_column_vlaues" select="./DBE:Attribute">
<xsl:with-param name="xrfItemHandle" select="$xrfItemHandle"/>
</xsl:apply-templates>
</TR>
</xsl:template>
<xsl:template mode="print_column_vlaues" match="DBE:Object/DBE:Attribute">
<xsl:param name="xrfItemHandle"/>
<xsl:param name="isRelation"/>
<xsl:variable name="columnName" select="./@name"/>
<xsl:if test="not(contains($columnName, 'OBID'))" >
<xsl:if test="not(contains($columnName, 'Class'))" >
<xsl:if test="not($columnName = 'Left' or $columnName = 'LeftMember')">
<xsl:if test="not($columnName = 'Right' or $columnName = 'RightMember')">
<xsl:if test="not($columnName = 'NavTplName' or $columnName = 'CustTplMsgName' or $columnName = 'CustTplMsgClassName' or $columnName = 'CustTplDialogName')">
<xsl:if test="not($columnName = 'XrfItemHandle')">
<xsl:apply-templates mode="print_filtered_column_vlaues" select=".">
<xsl:with-param name="xrfItemHandle" select="$xrfItemHandle"/>
<xsl:with-param name="isRelation" select="$isRelation"/>
</xsl:apply-templates>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template mode="print_filtered_column_vlaues" match="DBE:Object/DBE:Attribute">
<xsl:param name="xrfItemHandle"/>
<xsl:param name="isRelation"/>
<xsl:variable name="columnType" select="./@type"/>
<xsl:variable name="columnName" select="./@name"/>
<xsl:choose>
<xsl:when test="$columnName != 'DisplayedName' and $columnName != 'Class' and $columnType = 'String' ">
<xsl:variable name="transValue" select="./DBE:Translation"/>
<xsl:if test="string($transValue)" >
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="$transValue"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="not(string($transValue))" >
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="./DBE:String"/>
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:when test="$columnType = 'String' ">
<xsl:variable name="transValue" select="./DBE:Translation"/>
<xsl:if test="string($transValue)" >
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="$transValue"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="not(string($transValue))" >
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="./DBE:String"/>
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:when test="$columnType = 'Timestamp' ">
<xsl:variable name="transValue" select="./DBE:Translation"/>
<xsl:if test="string($transValue)" >
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="$transValue"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="not(string($transValue))" >
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="./DBE:Timestamp"/>
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:when test="$columnType = 'Boolean' ">
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="./DBE:Boolean"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$columnType = 'List' ">
<xsl:call-template name="print_list_column_value">
<xsl:with-param name="listValues" select="./DBE:List"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$columnType = 'Table' ">
<xsl:call-template name="print_table_column_value">
<xsl:with-param name="tableValues" select="./DBE:Table"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$columnType = 'StringStar' ">
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="./DBE:StringStar"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$columnType = 'Integer' ">
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="./DBE:Integer"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$columnType = 'Float' ">
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="./DBE:Float"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$columnType = 'Date' ">
<xsl:variable name="transValue" select="./DBE:Translation"/>
<xsl:if test="string($transValue)" >
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="$transValue"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="not(string($transValue))" >
<xsl:call-template name="print_column_value">
<xsl:with-param name="colValue" select="./DBE:Date"/>
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:when test="$columnType = 'Object' ">
<TD>
---
</TD>
</xsl:when>
<xsl:otherwise>
<TD>
---
</TD>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="print_displayed_name_column" >
<xsl:param name="colValue"/>
<xsl:param name="itemHandle"/>
<xsl:param name="isRelation"/>
<!-- move to global
<xsl:variable name="baseUrl" select="'http://mspm117:8080/change-l'"/>
-->
<xsl:if test="string($isRelation)">
<TD>
<xsl:value-of select="$colValue"/>
</TD>
</xsl:if>
<xsl:if test="not(string($isRelation))">
<xsl:if test="string($itemHandle)">
<xsl:variable name="relativeUrl"
select="'/controller/home?sdrcStartupPage=eds_open_generic_open_link&'"/>
<xsl:variable name="urlParams" select="'item_handle_param='"/>
<xsl:variable name="urlParamsValue" select="$itemHandle"/>
<xsl:if test="string($thinClientURLPrefix)">
<xsl:variable name="completeURL" select="concat($thinClientURLPrefix,$relativeUrl,
$urlParams,$urlParamsValue)"/>
<TD>
<a href="{$completeURL}" target="_blank">
<xsl:value-of select="$colValue"/>
</a>
</TD>
</xsl:if>
<xsl:if test="not(string($thinClientURLPrefix))">
<xsl:variable name="completeURL" select="concat($baseUrl,$relativeUrl,
$urlParams,$urlParamsValue)"/>
<TD>
<a href="{$completeURL}" target="_blank">
<xsl:value-of select="$colValue"/>
</a>
</TD>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template name="print_column_value" >
<xsl:param name="colValue"/>
<xsl:if test="string($colValue)">
<TD>
<xsl:value-of select="$colValue"/>
</TD>
</xsl:if>
<xsl:if test="not(string($colValue))">
<TD>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
</TD>
</xsl:if>
</xsl:template>
<xsl:template name="print_list_column_value" >
<xsl:param name="listValues"/>
<TD>
<TABLE>
<xsl:for-each select="$listValues/DBE:ListMember">
<xsl:variable name="listmemeber" select="."/>
<!-- FIXME: Dont know how to handle spaces inside string
normalize-space(.)
<xsl:value-of select="concat($listmemeber,',')" />
-->
<TR>
<xsl:value-of select="$listmemeber" />
</TR>
</xsl:for-each>
</TABLE>
</TD>
</xsl:template>
<xsl:template name="print_table_column_value" >
<xsl:param name="tableValues"/>
<TD>
<TABLE>
<xsl:for-each select="$tableValues/DBE:TableHeader">
<TR>
<xsl:variable name="tablecolumn" select="."/>
<xsl:for-each select="$tablecolumn/DBE:TableColumn">
<TD>
<xsl:value-of select="." />
</TD>
</xsl:for-each>
</TR>
</xsl:for-each>
<xsl:for-each select="$tableValues/DBE:TableRow">
<TR>
<xsl:variable name="tablerow" select="."/>
<xsl:for-each select="$tablerow/DBE:TableData">
<xsl:variable name="tabledata" select="."/>
<TD>
<xsl:value-of select="$tabledata" />
</TD>
</xsl:for-each>
</TR>
</xsl:for-each>
</TABLE>
</TD>
</xsl:template>
<xsl:template name="GetTextFromBundle">
<xsl:param name="textBundle" select="$defaultTextBundleRoot"/>
<xsl:param name="textID"/>
<xsl:variable name="text"
select="$defaultTextBundleRoot/IDMap/TextID[@name=$textID]/@text"/>
<xsl:choose>
<xsl:when test="string-length($text) > '0'">
<xsl:value-of select="$text"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$textID" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
这是xml
<?xml-stylesheet type="text/xsl" href="ECNSIGNOFF_default_html_classic_StylesheetF.xsl"?>
<!--
The DOCTYPE command is commented out for Internet Explorer compatibility.
<!DOCTYPE DBE:ObjectSetRoot SYSTEM "/ees/pdm/apps/epi/sb/tc8.1/product/xml/bd2.dtd">
--><DBE:ObjectSetRoot xmlns:DBE="http://www.sdrc.com/metaphase/cf11bd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sdrc.com/metaphase/cf11bd /ees/pdm/apps/epi/sb/tc8.1/product/xml/bd2.xsd">
<DBE:Object Class="x1ENSREB">
<DBE:Attribute name="Class" type="String" displayAs="Class" length="20">
<DBE:String>x1ENSREB</DBE:String>
<DBE:Translation>ECN-NSR Implements Document</DBE:Translation>
</DBE:Attribute>
<DBE:Attribute name="x0ChgDesc" type="String" displayAs="Description of Change (what?)" length="2000">
<DBE:String>ECN</DBE:String>
</DBE:Attribute>
<DBE:Attribute name="x0EcnChgType" type="String" displayAs="Type of Change" length="20">
<DBE:String>x0NSR</DBE:String>
<DBE:Translation>Non-saleable</DBE:Translation>
</DBE:Attribute>
</DBE:Object>
<DBE:Object Class="x4SvcPln">
<DBE:Attribute name="Class" type="String" displayAs="Class" length="20">
<DBE:String>x4SvcPln</DBE:String>
<DBE:Translation>Service Plan</DBE:Translation>
</DBE:Attribute>
<DBE:Attribute name="Creator" type="String" displayAs="Last Modified By" length="30">
<DBE:String>super user</DBE:String>
</DBE:Attribute>
<DBE:Attribute name="DocumentName" type="String" displayAs="Document Number" length="80">
<DBE:String>SP000001</DBE:String>
</DBE:Attribute>
</DBE:Object>
<DBE:Object Class="DocSig">
<DBE:Attribute name="Class" type="String" displayAs="Class" length="20">
<DBE:String>DocSig</DBE:String>
<DBE:Translation>DocSig</DBE:Translation>
</DBE:Attribute>
<DBE:Attribute name="CurrentUser" type="String" displayAs="Current Assigned User" length="80">
<DBE:String>super user</DBE:String>
</DBE:Attribute>
<DBE:Attribute name="ExtStamp" type="String" displayAs="Signature Stamp" length="30">
<DBE:String/>
</DBE:Attribute>
</DBE:Object>
<DBE:Object Class="DocSig">
<DBE:Attribute name="Class" type="String" displayAs="Class" length="20">
<DBE:String>DocSig</DBE:String>
<DBE:Translation>DocSig</DBE:Translation>
</DBE:Attribute>
<DBE:Attribute name="CurrentUser" type="String" displayAs="Current Assigned User" length="80">
<DBE:String>super user</DBE:String>
</DBE:Attribute>
<DBE:Attribute name="ExtStamp" type="String" displayAs="Signature Stamp" length="30">
<DBE:String/>
</DBE:Attribute>
</DBE:Object>
<DBE:Object Class="DocSig">
<DBE:Attribute name="Class" type="String" displayAs="Class" length="20">
<DBE:String>DocSig</DBE:String>
<DBE:Translation>DocSig</DBE:Translation>
</DBE:Attribute>
<DBE:Attribute name="CurrentUser" type="String" displayAs="Current Assigned User" length="80">
<DBE:String>Author</DBE:String>
</DBE:Attribute>
<DBE:Attribute name="ExtStamp" type="String" displayAs="Signature Stamp" length="30">
<DBE:String/>
</DBE:Attribute>
</DBE:Object>
<DBE:Object Class="x1ENSREB">
<DBE:Attribute name="Class" type="String" displayAs="Class" length="20">
<DBE:String>x1ENSREB</DBE:String>
<DBE:Translation>ECN-NSR Implements Document</DBE:Translation>
</DBE:Attribute>
<DBE:Attribute name="x0ChgDesc" type="String" displayAs="Description of Change (what?)" length="2000">
<DBE:String>test ECN</DBE:String>
</DBE:Attribute>
<DBE:Attribute name="x0EcnChgType" type="String" displayAs="Type of Change" length="20">
<DBE:String>x0NSR</DBE:String>
<DBE:Translation>Non-saleable</DBE:Translation>
</DBE:Attribute>
</DBE:Object>
<DBE:Object Class="x4SvcPln">
<DBE:Attribute name="Class" type="String" displayAs="Class" length="20">
<DBE:String>x4SvcPln</DBE:String>
<DBE:Translation>Service Plan</DBE:Translation>
</DBE:Attribute>
<DBE:Attribute name="Creator" type="String" displayAs="Last Modified By" length="30">
<DBE:String>super user</DBE:String>
</DBE:Attribute>
<DBE:Attribute name="DocumentName" type="String" displayAs="Document Number" length="80">
<DBE:String>SP000002</DBE:String>
</DBE:Attribute>
</DBE:Object>
<DBE:Object Class="DocSig">
<DBE:Attribute name="Class" type="String" displayAs="Class" length="20">
<DBE:String>DocSig</DBE:String>
<DBE:Translation>DocSig</DBE:Translation>
</DBE:Attribute>
<DBE:Attribute name="CurrentUser" type="String" displayAs="Current Assigned User" length="80">
<DBE:String>super user</DBE:String>
</DBE:Attribute>
<DBE:Attribute name="ExtStamp" type="String" displayAs="Signature Stamp" length="30">
<DBE:String/>
</DBE:Attribute>
</DBE:Object>
<DBE:Object Class="DocSig">
<DBE:Attribute name="Class" type="String" displayAs="Class" length="20">
<DBE:String>DocSig</DBE:String>
<DBE:Translation>DocSig</DBE:Translation>
</DBE:Attribute>
<DBE:Attribute name="CurrentUser" type="String" displayAs="Current Assigned User" length="80">
<DBE:String>consumer</DBE:String>
</DBE:Attribute>
<DBE:Attribute name="ExtStamp" type="String" displayAs="Signature Stamp" length="30">
<DBE:String/>
</DBE:Attribute>
</DBE:Object>
</DBE:ObjectSetRoot>
答案 0 :(得分:0)
您需要做的是替换此行
<xsl:apply-templates mode="print_unique_classes"
select="/DBE:ObjectSetRoot/DBE:Object
[not(./@Class=preceding-sibling::DBE:Object/@Class)]"/>
使用此行
<xsl:apply-templates mode="print_unique_classes"
select="/DBE:ObjectSetRoot/DBE:Object
[not(./@Class=preceding-sibling::DBE:Object[1]/@Class)]"/>
DBE:Object [1] 会将检查限制在此处仅查看前面的第一个兄弟。
此外,您还需要获取“表格”中的所有项目。在“print_item_class”的模板中,您可能需要替换此行
<xsl:apply-templates mode="print_similar_item_classes"
select="/DBE:ObjectSetRoot/DBE:Object[@Class=$className]"/>
使用此行
<xsl:apply-templates
select="following-sibling::DBE:Object[1][@Class=current()/@Class]"
mode="print_item_class" />
您当前的行将获得具有相同类的所有项目,而修改后的行只会在类更改之前获得具有相同名称的以下兄弟。
有时候,最好简化问题。将它简化为最基本的,并以此为基础。试试这个XLST例如:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:DBE="http://www.sdrc.com/metaphase/cf11bd" exclude-result-prefixes="DBE">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:apply-templates select="/DBE:ObjectSetRoot/DBE:Object[not(./@Class=preceding-sibling::DBE:Object[1]/@Class)]" mode="print_unique_classes"/>
</xsl:template>
<xsl:template match="DBE:Object" mode="print_unique_classes">
<ul>
<xsl:apply-templates select="." mode="print_item_class" />
</ul>
</xsl:template>
<xsl:template match="DBE:Object" mode="print_item_class">
<li><xsl:value-of select="@Class" /></li>
<xsl:apply-templates select="following-sibling::DBE:Object[1][@Class=current()/@Class]" mode="print_item_class" />
</xsl:template>
</xsl:stylesheet>
应用于XML时,输出以下内容。我有输出列表而不是表格,只是为了证明原理。
<ul>
<li>x1ENSREB</li>
</ul>
<ul>
<li>x4SvcPln</li>
</ul>
<ul>
<li>DocSig</li>
<li>DocSig</li>
<li>DocSig</li>
</ul>
<ul>
<li>x1ENSREB</li>
</ul>
<ul>
<li>x4SvcPln</li>
</ul>
<ul>
<li>DocSig</li>
<li>DocSig</li>
</ul>
现在,如果你可以使用XSLT2.0,那么 xsl:for-each-group 可能是你最好的朋友。试试这个XSLT
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:DBE="http://www.sdrc.com/metaphase/cf11bd" exclude-result-prefixes="DBE">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:for-each-group select="DBE:Object" group-adjacent="@Class">
<ul>
<xsl:for-each select="current-group()">
<li>
<xsl:value-of select="@Class"/>
</li>
</xsl:for-each>
</ul>
<xsl:text/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
这也应该给出相同的结果。
希望你能够在此基础上输出你想要的表格。