xml – XSLT中的对列表中的值替换

我正在使用XSLT从一种格式的
XML转换为另一种格式,但如果可能的话,我还需要同时进行一些值替换.有人可以提供改变大量价值的解决方案;例如“AppName”应更改为“1”,“AppNameTwo”更改为“2”,我希望通过XSLT中的某些类型的查找列表来执行此操作:

<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(如果不为空)或当前节点.

点赞