如何复制属性?
How to copy attributes?
输入xml文件:
<root>
<x1 attr11="sd5">
<x2 attr12="sd6" attr15="sd7">
<a />
<b>
<x3 attr18="sd8">
<c>
<x4 attr19="sd9"/>
<d />
<e />
</c>
</x3>
</b>
</x2>
</x1>
</root>
从中获取更新的“updates.xml”文件 - 标记属性:
<updates>
<a attr1="adf" attr2="67" />
<b attr3="g6h"/>
<c attr4="7jj" />
<d attr5="88" attr6="mn4" />
<e />
</updates>
如果输入文件包含“updates.xml”文件中的标签(无属性),则“updates.xml”文件中的属性会被复制到其中。 XSLT1.0 转换后的文件应该是这样的:
<root>
<x1 attr11="sd5">
<x2 attr12="sd6" attr15="sd7">
<a attr1="adf" attr2="67" />
<b attr3="g6h">
<x3 attr18="sd8">
<c attr4="7jj">
<x4 attr19="sd9"/>
<d attr5="88" attr6="mn4" />
<e />
</c>
</x3>
</b>
</x2>
</x1>
</root>
现在这是 XSLT1.0 转换文件:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="exslt"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="updates" select="document('updates.xml')"/>
<xsl:key name="replacement" match="//*" use="local-name()"/>
<!--Identity template-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(node())]">
<xsl:variable name="element" select="(.)"/>
<xsl:variable name="replacement">
<xsl:for-each select="$updates">
<xsl:copy-of select="key('replacement', local-name($element))"/>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="exslt:node-set($replacement)/*">
<xsl:copy-of select="$replacement"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="(.)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
XML 转换后的文件:
<root>
<x1 attr11="sd5">
<x2 attr12="sd6" attr15="sd7">
<a attr1="adf" attr2="67" />
<b>
<x3 attr18="sd8">
<c>
<x4 attr19="sd9" />
<d attr5="88" attr6="mn4" />
<e />
</c>
</x3>
</b>
</x2>
</x1>
</root>
为什么不将属性复制到 'b' 和 'c' 标签?
使用 apply-templates
处理原始属性以及来自其他文档的属性(即身份转换)并保持递归处理:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="exslt"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="updates" select="document('updates.xml')"/>
<xsl:key name="replacement" match="*" use="local-name()"/>
<!--Identity template-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:variable name="this" select="."/>
<xsl:for-each select="$updates">
<xsl:apply-templates select="key('replacement', local-name($this))/@*"/>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输入xml文件:
<root>
<x1 attr11="sd5">
<x2 attr12="sd6" attr15="sd7">
<a />
<b>
<x3 attr18="sd8">
<c>
<x4 attr19="sd9"/>
<d />
<e />
</c>
</x3>
</b>
</x2>
</x1>
</root>
从中获取更新的“updates.xml”文件 - 标记属性:
<updates>
<a attr1="adf" attr2="67" />
<b attr3="g6h"/>
<c attr4="7jj" />
<d attr5="88" attr6="mn4" />
<e />
</updates>
如果输入文件包含“updates.xml”文件中的标签(无属性),则“updates.xml”文件中的属性会被复制到其中。 XSLT1.0 转换后的文件应该是这样的:
<root>
<x1 attr11="sd5">
<x2 attr12="sd6" attr15="sd7">
<a attr1="adf" attr2="67" />
<b attr3="g6h">
<x3 attr18="sd8">
<c attr4="7jj">
<x4 attr19="sd9"/>
<d attr5="88" attr6="mn4" />
<e />
</c>
</x3>
</b>
</x2>
</x1>
</root>
现在这是 XSLT1.0 转换文件:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="exslt"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="updates" select="document('updates.xml')"/>
<xsl:key name="replacement" match="//*" use="local-name()"/>
<!--Identity template-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(node())]">
<xsl:variable name="element" select="(.)"/>
<xsl:variable name="replacement">
<xsl:for-each select="$updates">
<xsl:copy-of select="key('replacement', local-name($element))"/>
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="exslt:node-set($replacement)/*">
<xsl:copy-of select="$replacement"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="(.)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
XML 转换后的文件:
<root>
<x1 attr11="sd5">
<x2 attr12="sd6" attr15="sd7">
<a attr1="adf" attr2="67" />
<b>
<x3 attr18="sd8">
<c>
<x4 attr19="sd9" />
<d attr5="88" attr6="mn4" />
<e />
</c>
</x3>
</b>
</x2>
</x1>
</root>
为什么不将属性复制到 'b' 和 'c' 标签?
使用 apply-templates
处理原始属性以及来自其他文档的属性(即身份转换)并保持递归处理:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="exslt"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="updates" select="document('updates.xml')"/>
<xsl:key name="replacement" match="*" use="local-name()"/>
<!--Identity template-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:variable name="this" select="."/>
<xsl:for-each select="$updates">
<xsl:apply-templates select="key('replacement', local-name($this))/@*"/>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>