问题描述
|
我有一个看起来像这样的XML
<executionPlan name=\"Test\" >
<paramList>
<param name=\"param1\" default=\"\"/>
</paramList>
<varList>
<var name=\"bla\" default=\":[param1]\"/>
</varList>
<simpleSteps limitToHostSet=\"bla\">
<execNative>
<exec cmd=\"/bin/sh\"/>
</execNative>
</simpleSteps>
我需要将其转换为如下形式:
<executionPlan name=\"Test\" >
<paramList>
<param name=\"param1\" default=\"\"/>
</paramList>
<simpleSteps limitToHostSet=\"bla\">
<varList>
<var name=\"bla\" default=\":[param1]\"/>
</varList>
<execNative>
<exec cmd=\"/bin/sh\"/>
</execNative>
</simpleSteps>
如您所见,varList元素需要嵌套在simpleTags元素内,紧接在开始标记之后。 simpleSteps中可能还有其他varList元素,不能更改。
有什么想法可以使用XSLT实现吗?我是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=\"varList[following-sibling::*[1][self::simpleSteps]]\" />
<xsl:template match=\"simpleSteps\">
<xsl:copy>
<xsl:apply-templates select=\"@*\" />
<xsl:copy-of select=\"preceding-sibling::varList[1]\" />
<xsl:apply-templates select=\"node()\" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在此输入上:
<executionPlan name=\"Test\">
<paramList>
<param name=\"param1\" default=\"\" />
</paramList>
<varList>
<var name=\"bla\" default=\":[param1]\" />
</varList>
<varList>
<var name=\"bla2\" default=\":[param2]\" />
</varList>
<simpleSteps limitToHostSet=\"bla\">
<execNative>
<exec cmd=\"/bin/sh\" />
</execNative>
</simpleSteps>
</executionPlan>
产生:
<executionPlan name=\"Test\">
<paramList>
<param name=\"param1\" default=\"\" />
</paramList>
<varList>
<var name=\"bla\" default=\":[param1]\" />
</varList>
<simpleSteps limitToHostSet=\"bla\">
<varList>
<var name=\"bla2\" default=\":[param2]\" />
</varList>
<execNative>
<exec cmd=\"/bin/sh\" />
</execNative>
</simpleSteps>
</executionPlan>
编辑:仅将紧前面的ѭ5移入与其关联的simpleSteps
。所有其他“ 5”元素均原样复制。
我突然不清楚这是否是所需的行为,或者在or6ѭ元素内是否已有多个varList
元素应该保持不变。对于这种情况,请参阅我的原始解决方案:
<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=\"varList\" />
<xsl:template match=\"simpleSteps\">
<xsl:copy>
<xsl:apply-templates select=\"@*\" />
<xsl:copy-of select=\"../varList\" />
<xsl:apply-templates select=\"node()\" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在此输入上:
<executionPlan name=\"Test\">
<paramList>
<param name=\"param1\" default=\"\" />
</paramList>
<varList>
<var name=\"bla\" default=\":[param1]\" />
</varList>
<simpleSteps limitToHostSet=\"bla\">
<varList>
<var name=\"bla7\" default=\":[param7]\" />
</varList>
<execNative>
<exec cmd=\"/bin/sh\" />
</execNative>
</simpleSteps>
</executionPlan>
产生:
<executionPlan name=\"Test\">
<paramList>
<param name=\"param1\" default=\"\" />
</paramList>
<simpleSteps limitToHostSet=\"bla\">
<varList>
<var name=\"bla\" default=\":[param1]\" />
</varList>
<varList>
<var name=\"bla7\" default=\":[param7]\" />
</varList>
<execNative>
<exec cmd=\"/bin/sh\" />
</execNative>
</simpleSteps>
</executionPlan>
,这是一个更简单,更短的解决方案:
<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()|@*\" name=\"identity\">
<xsl:copy>
<xsl:apply-templates select=\"node()|@*\"/>
</xsl:copy>
</xsl:template>
<xsl:template match=\"simpleSteps/*[1]\">
<xsl:copy-of select=\"/*/varList[1]\"/>
<xsl:call-template name=\"identity\"/>
</xsl:template>
<xsl:template match=\"/*/varList[1]\"/>
</xsl:stylesheet>
当应用于提供的XML文档时:
<executionPlan name=\"Test\" >
<paramList>
<param name=\"param1\" default=\"\"/>
</paramList>
<varList>
<var name=\"bla\" default=\":[param1]\"/>
</varList>
<simpleSteps limitToHostSet=\"bla\">
<execNative>
<exec cmd=\"/bin/sh\"/>
</execNative>
</simpleSteps>
</executionPlan>
正是想要的,正确的结果产生了:
<executionPlan name=\"Test\">
<paramList>
<param name=\"param1\" default=\"\"/>
</paramList>
<simpleSteps limitToHostSet=\"bla\">
<varList>
<var name=\"bla\" default=\":[param1]\"/>
</varList>
<execNative>
<exec cmd=\"/bin/sh\"/>
</execNative>
</simpleSteps>
</executionPlan>
说明:
身份规则/模板按“原样”复制每个节点。只有两个例外,如下所述。
仅匹配top元素的第一个“ 5”子元素的覆盖模板没有主体-这实际上废除了此元素的身份模板的复制操作。
匹配simpleSteps
的第一个元素子元素的覆盖模板有两件事:a)复制所需的varList
(顶部元素的子元素),然后b)调用身份模板将自身复制到输出。