我在编写简单的XSLT转换时遇到了麻烦。这是XML数据:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<lst name="params">
</lst>
</lst>
<result name="response" numFound="2" start="0">
<doc>
<str name="Race">Elf</str>
<int name="TraderKey">128</int>
<str name="TraderName">TraderLato</str>
<int name="CharacterName">Maleysh</int>
</doc>
<doc>
<str name="Race">Human</str>
<int name="TraderKey">62</int>
<str name="TraderName">TraderSam</str>
<int name="Comments">Farl</int>
</doc>
</result>
</response>
我无法修改XML的格式,并且会有很多很多节点。我需要能够编写一个XSLT 1.0转换,它将复制所有原始XML,但替换某些TraderKey值的TraderName。在包含TraderKey为128的任何节点上,将TraderName更改为“Trader Lato Carum”。包含TraderKey为62的任何一个,将TraderName更改为“Trader Samson Vero”。我之前从未编写过XSLT,并且对XML的经验有限,所以这是我尝试编写XSLT转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="response/result/doc/int[@name='TraderKey'][. = '128']>
<xsl:value-of select="../TraderName"/>
<xsl:text>Trader Lato Carum</xsl:text>
</xsl:template>
<xsl:template match="response/result/doc/int[@name='TraderKey'][. = '62']>
<xsl:value-of select="../TraderName"/>
<xsl:text>Trader Samson Vero</xsl:text>
</xsl:template>
</xsl:stylesheet>
它根本不起作用,过去一小时我一直在用头撞墙。我不认为这应该是一个难题,我做错了什么?
由于 zoombini
答案 0 :(得分:1)
你在正确的界限上有你所进行的身份/复制模式,你只需要一点条件输出。
this XMLPlayground的演示(请参阅输出来源)
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select='@*' />
<xsl:apply-templates select='*' />
<xsl:choose>
<xsl:when test='@name = "TraderName" and preceding-sibling::*[@name = "TraderKey"] = 62'>
Trader Samson Vero
</xsl:when>
<xsl:when test='@name = "TraderName" and preceding-sibling::*[@name = "TraderKey"] = 128'>
Trader Lato Carum
</xsl:when>
<xsl:otherwise>
<xsl:value-of select='text()' />
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
答案 1 :(得分:0)
解决方案可以很简单,采用纯推送方式(没有显式xsl:apply-templates
),不使用任何XSLT条件指令(例如xsl:choose
,xsl:when
,{{1 }}) - 因此更短,更易读和易懂:
xsl:otherwise
在提供的XML文档上应用此转换时:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"*[int[@name='TraderKey'] = 128]
/str[@name='TraderName']
/text()">
<xsl:text>Trader Lato Carum</xsl:text>
</xsl:template>
<xsl:template match=
"*[int[@name='TraderKey'] = 62]
/str[@name='TraderName']
/text()">
<xsl:text>Trader Samson Vero</xsl:text>
</xsl:template>
</xsl:stylesheet>
产生了想要的正确结果:
<response>
<lst name="responseHeader">
<lst name="params"></lst></lst>
<result name="response" numFound="2" start="0">
<doc>
<str name="Race">Elf</str>
<int name="TraderKey">128</int>
<str name="TraderName">TraderLato</str>
<int name="CharacterName">Maleysh</int>
</doc>
<doc>
<str name="Race">Human</str>
<int name="TraderKey">62</int>
<str name="TraderName">TraderSam</str>
<int name="Comments">Farl</int>
</doc>
</result>
</response>