我有来自供应商的源XML:
<?xml version="1.0" encoding="UTF-8"?>
<src:view name="books"
xmlns="xyz.com/wow"
xmlns:src="xyz.com/fun"
xmlns:xsi="w3.org/2001/XMLSchema-instance">
<books>
<title>Searching for Answers</title>
</books>
<books>
<title>Get Rich Quick</title>
</books>
<books>
<title>Negotiating with the Grim Reaper</title>
</books>
</src:view>
我想转换为具有根元素books
的新文档,然后复制所有books
元素,但将名称从books
更改为books_record
。文档将是任意的,( books 今天,小部件明天等),但是根的子元素的元素名称始终可以从/@name
获得,这是供应商约定。
<books>
<books_record>
<title>Searching for Answers</title>
</books_record>
<books_record>
<title>Get Rich Quick</title>
</books_record>
<books_record>
<title>Negotiating with the Grim Reaper</title>
</books_record>
</books>
我管理了权利根元素并复制了所有子元素,但我不确定如何将所有<books>
更改为<books_record>
。而且,到目前为止我的效率和有效性是多少?我知道它有效,但不是100%确定它是否是最好的方法。
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="xsl" version="2.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="/*">
<xsl:variable name="rootElementName">
<xsl:value-of select="@name" />
</xsl:variable>
<xsl:element name="{$rootElementName}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="/*/node()">
<xsl:variable name="rootElementName">
<xsl:value-of select="/*/@name" />
</xsl:variable>
<xsl:element name="{$rootElementName}_record">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
</xsl:transform>
答案 0 :(得分:2)
我相信你可以将其简化为:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="/*">
<books>
<xsl:apply-templates />
</books>
</xsl:template>
<xsl:template match="*[local-name()='books']">
<books_record>
<xsl:apply-templates />
</books_record>
</xsl:template>
</xsl:transform>
当然,如果你知道输入的预期格式,你可以更明确 - 因此更短的和更有效,例如:
<xsl:transform version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:src="xyz.com/fun"
xmlns:wow="xyz.com/wow"
exclude-result-prefixes="src wow">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<books>
<xsl:for-each select="src:view/wow:books">
<books_record>
<title>
<xsl:value-of select="wow:title"/>
</title>
</books_record>
</xsl:for-each>
</books>
</xsl:template>
</xsl:transform>
如果我正确理解你的意思是&#34; generic&#34;,那么:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:variable name="tableName" select="/*/@name" />
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*" />
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="/*">
<xsl:element name="{$tableName}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="*/*">
<xsl:element name="{$tableName}_record">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:transform>
注意:
exclude-result-prefixes="xsl"