[XSLT难题 No.5][200分]
这个帖子给200分,因为我等级不够,等解决后我再开一个帖子,补上另外的100分,谢谢
一。需求
1.给定一个字符串变量,例如"_en"
2.找到源文档中的<Spec>元素,递归扫描<Spec>为根节点的子文档树,找到所有名称结尾是"_en"的属性,例如"abc_en","def_en"等等
3.搜索找到的属性例如"abc_en"所在的元素,判断其是否含有名为"abc"(也就是"abc_en" substring "_en" = "abc")的属性
4.如果存在"abc"属性,那么交换"abc"属性和"abc_en"属性的值
5.如果不存在,那么和文档中的其它内容一样,原封不动copy到目的文档
6.总的来说,就是要交换第2.3.4步中符合条件的属性值,其余的不动,生成目的文档
二。源xml文档
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- edited with XMLSPY v5 U (http://www.xmlspy.com) by a (a) -->
<ObjectPersistSpace>
<Spec key="c" oemId="EGFM28" oemName="EGFM28" policy="manage" mem="中文" mem_en="English">
<sub>
<SHRSpecSub key="p" lim="9">
<lst>
<SHRSpecSubVal ins="fixed" spec="FEWPort" value="1"/>
<SHRSpecSubVal ins="fixed" spec="FEWPort" value="2"/>
<SHRSpecSubVal ins="fixed" spec="FEWPort" value="3"/>
<SHRSpecSubVal ins="fixed" spec="FEWPort" value="4"/>
<SHRSpecSubVal ins="fixed" spec="FEWPort" value="5"/>
<SHRSpecSubVal ins="fixed" spec="FEWPort" value="6"/>
<SHRSpecSubVal ins="fixed" spec="FEWPort" value="7"/>
<SHRSpecSubVal ins="fixed" spec="FEWPort" value="8"/>
</lst>
</SHRSpecSub>
<SHRSpecSub key="c" lim="3">
<lst>
<SHRSpecSubVal ins="fixed" spec="CFE08" value="1"/>
<SHRSpecSubVal ins="fixed" spec="CGE02" value="2"/>
</lst>
</SHRSpecSub>
</sub>
<fprp>
<SHRSpecFPrp fprp="feCfg" disp="积分软卧耳机哦我" disp_en="enjsdofuwoer" mem="殴打开发公平" mem_en="ejrlfenldfo">
<val teid="Boolean" val="true"/>
</SHRSpecFPrp>
</fprp>
<mprp>
<SHRSpecMPrp mprp="verInfo" disp="中文使得玩儿据我" disp_en="englishsdfjoweuru" mem="" mem_en="" mode="RO" teid="HRVerInfo_Seq"/>
</mprp>
<cprp/>
<alm>
<SHRSpecAlm id="9" src="" _id="ChssOffLine"/>
<SHRSpecAlm id="67" src="" _id="ChssFault"/>
</alm>
<per/>
<view icon="card_i.gif" map="" photo=""/>
</Spec>
</ObjectPersistSpace>
三。xslt文档。我自己写了一个,但跑起来后有问题,仅仅把所有属性copy过来了,请教一下高手,该如何修改呢,并说说我错在哪里,谢谢
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- out format -->
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- language variable, e.g. "_en" -->
<xsl:variable name="language">_en</xsl:variable>
<!-- top template -->
<xsl:template match="/">
<xsl:apply-templates select="node()"/>
</xsl:template>
<!-- recurse template for scanning nodes-->
<xsl:template match="node()">
<!-- scan attributes -->
<xsl:for-each select="@*">
<!-- suffix variable -->
<xsl:variable name="suffix">
<xsl:value-of select="substring(name(), string-length(name()) - string-length($language) + 1, string-length(name()))"/>
</xsl:variable>
<!-- prefix variable -->
<xsl:variable name="prefix">
<xsl:value-of select="substring(name(), 0, string-length(name()) - string-length($language) + 1)"/>
</xsl:variable>
<!-- If being a attribute which name's ending contains language variable -->
<xsl:choose>
<xsl:when test="$suffix = $language">
<xsl:choose>
<xsl:when test="../@*[name() = $prefix]">
<xsl:call-template name="TransformTemplate">
<xsl:with-param name="defaultContent">
<xsl:value-of select="$prefix"/>
</xsl:with-param>
<xsl:with-param name="languageContent">
<xsl:value-of select="concat($prefix, $suffix)"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="CopyTemplate"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
</xsl:template>
<!-- element copy template -->
<xsl:template name="CopyTemplate">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<!-- element transform template -->
<xsl:template name="TransformTemplate">
<xsl:param name="defaultContent"/>
<xsl:param name="languageContent"/>
<xsl:variable name="temp">
<xsl:value-of select="../@*[name()=$languageContent]"/>
</xsl:variable>
<xsl:copy>
<xsl:copy-of select="../@*[name() != $defaultContent and name() != $languageContent]"/>
<xsl:attribute name="{$languageContent}"><xsl:value-of select="../@*[name()=$defaultContent]"/></xsl:attribute>
<xsl:attribute name="{$defaultContent}"><xsl:value-of select="$temp"/></xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>