在我以前的 question中,我问过如何在简单的XML中将特定属性转换为元素.现在我有更复杂的输入. 我需要将属性’query’转换为元素. 复杂输入: ?xml version="1.0" encoding="UTF-8" standalone="yes"?f
我需要将属性’query’转换为元素.
复杂输入:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <filter query="select" name="hello" description="world"> <certification>WFA</certification> <uuid>fd5d9f15-f6d9-4e71-aaf4-024aaaa627f2</uuid> <parameters> <parameter type="STRING" name="name" label="name"> <description>Some name</description> </parameter> </parameters> <returned-attributes> <returned-attribute>id</returned-attribute> </returned-attributes> </filter>
我的愿望输出如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <filter name="hello" description="world"> <certification>WFA</certification> <uuid>fd5d9f15-f6d9-4e71-aaf4-024aaaa627f2</uuid> <query>select<query/> <parameters> <parameter type="STRING" name="name" label="name"> <description>Some name</description> </parameter> </parameters> <returned-attributes> <returned-attribute>id</returned-attribute> </returned-attributes> </filter>
我使用以下XSLT:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:strip-space elements="*"/> <xsl:output indent="yes"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- match the filter element --> <xsl:template match="filter"> <xsl:choose> <xsl:when test="/filter/@query"> <!-- output a filter element --> <xsl:element name="filter"> <!-- add the name attribute, using the source name attribute value --> <xsl:attribute name="name"> <xsl:value-of select="@name"/> </xsl:attribute> <!-- add the description attribute (if found), using the source name attribute value --> <xsl:choose> <xsl:when test="/filter/@description"> <xsl:attribute name="description"> <xsl:value-of select="@description"/> </xsl:attribute> </xsl:when> </xsl:choose> <!-- add the query as child element, using the source query attribute value --> <xsl:element name="query"> <xsl:value-of select="@query"/> </xsl:element> <!-- add all common elements --> <xsl:element name="certification"> <xsl:value-of select="certification"/> </xsl:element> <xsl:element name="uuid"> <xsl:value-of select="uuid"/> </xsl:element> <!-- copy parameters --> <xsl:copy> <xsl:apply-templates select="/filter/parameters"/> </xsl:copy> <!-- copy attributes --> <xsl:copy> <xsl:apply-templates select="/filter/returned-attributes"/> </xsl:copy> </xsl:element> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
转型有效,但在我看来很复杂.
注意,我使用if / else逻辑,因为我的输入可以包含“old”(未转换)和
“新”(转换)的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="parameters"> <xsl:apply-templates select="/filter/@query" mode="build"/> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="/filter/@query"/> <xsl:template match="/filter/@query" mode="build"> <query><xsl:value-of select="."/></query> </xsl:template> </xsl:stylesheet>
当此转换应用于提供的XML文档时:
<filter query="select" name="hello" description="world"> <certification>WFA</certification> <uuid>fd5d9f15-f6d9-4e71-aaf4-024aaaa627f2</uuid> <parameters> <parameter type="STRING" name="name" label="name"> <description>Some name</description> </parameter> </parameters> <returned-attributes> <returned-attribute>id</returned-attribute> </returned-attributes> </filter>
产生了想要的正确结果:
<filter name="hello" description="world"> <certification>WFA</certification> <uuid>fd5d9f15-f6d9-4e71-aaf4-024aaaa627f2</uuid> <query>select</query> <parameters> <parameter type="STRING" name="name" label="name"> <description>Some name</description> </parameter> </parameters> <returned-attributes> <returned-attribute>id</returned-attribute> </returned-attributes> </filter>