我正在使用XSLT从一种格式的 XML转换为另一种格式,但如果可能的话,我还需要同时进行一些值替换.有人可以提供改变大量价值的解决方案;例如“AppName”应更改为“1”,“AppNameTwo”更改为
<Application> <oldvalue="AppName" replacewith="1"> <oldvalue="AppNameTwo" replacewith="2"> </Application> <ResponseOne> <oldvalue="True" replacewith="Okay"> <oldvalue="False" replacewith="Error"> </ResponseOne>
我目前可以想到这样做的唯一方法是通过许多嵌套替换?
输入
<Message> <Header> <Application>AppName</Application> <ResponseOne>True</ResponseOne> ... </Header> </Message>
XSLT到目前为止
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0"> <xsl:template match="/"> <n1:Message> <Header> <Application><xsl:value-of select="//Message/Organisation/Application/Name"/> </Application> <Response><xsl:value-of select="//Message/Organisation/Application/ResponseOne"/> </Response> ... </Header> </n1:Message>
要求的输出
<?xml version="1.0" encoding="utf-8"?> <n1:Message> <Header> <Application>1</Application> <Response>Error</Response> ... </Header> </n1:Message>
打算在Visual Studio 2010中运行此XSLT.
这种简单的转换(只有一个模板覆盖了身份规则,不需要扩展功能),允许使用大量的替换规则,而根本不需要更改代码.另一种方法是在转换之外指定全局参数$pReps的值 – 然后这个代码甚至可以略微简化:<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:param name="pReps"> <elem name="Application"> <replace> <this>AppName</this> <with>1</with> </replace> <replace> <this>AppNameTwo</this> <with>2</with> </replace> </elem> <elem name="ResponseOne"> <replace> <this>True</this> <with>Okay</with> </replace> <replace> <this>False</this> <with>Error</with> </replace> </elem> </xsl:param> <xsl:variable name="vReps" select= "document('')/*/xsl:param[@name='pReps']"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="text()"> <xsl:variable name="vNewVal" select= "$vReps/elem [@name=name(current()/..)] /replace[this = current()] /with/text() "/> <xsl:copy-of select= "$vNewVal | self::text()[not($vNewVal)]"/> </xsl:template> </xsl:stylesheet>
应用于提供的XML文档时:
<Message> <Header> <Application>AppName</Application> <ResponseOne>True</ResponseOne> ... </Header> </Message>
产生了想要的正确结果:
<Message> <Header> <Application>1</Application> <ResponseOne>Okay</ResponseOne> ... </Header> </Message>
说明:
> identity rule(模板)“按原样”复制每个节点.>替换规则被编码为elem元素的序列,这些元素是全局参数pReps的子元素.每个元素的结构和含义应该是不言自明的.>有一个模板覆盖身份规则,匹配任何文本节点.在此模板中,计算可能的新值,由变量$vNewVal定义.这是空节点集(如果当前节点的父名称和当前节点的字符串值未被$pReps中的任何替换/此值匹配.或者,如果匹配,则这是兄弟节点来自$pReps的匹配替换/ this值.最后,复制$vNewVal(如果不为空)或当前节点.