使用 XSLT脚本修改XML节点

我想select一个节点,并使用xsl:script函数修改其属性和子节点。 另外,匹配那个节点的子节点的模板应该仍然执行它们的工作(在脚本完成处理节点之后)。

  1. 可以使用XSLT来完成吗?
  2. 你能提供一个例子/骨架进行这样的转换吗?

是的,可以做到。 我似乎没有看到问题是什么,因为XSL脚本的XML(或任何输出)被独立于其输入缓冲。

在下面的例子中说明了这一点,一个简单的XSL脚本主要按原样复制一个输入XML文档,并改变了一些事情:

  • 根元素名称和属性
  • 通过从层次结构中移除元素来展平
  • 删除结果/日期元素
  • 重命名项目的“源”属性“起源”
  • 更改项目的“级别”属性值
  • 重命名项目元素的名字和姓氏元素

示例输入

<?xml version="1.0" encoding="ISO-8859-1"?> <MyRoot version="1.2"> <results> <info>Alpha Bravo</info> <author>Employee No 321</author> <date/> <item source="www" level="6" cost="33"> <FirstName>Jack</FirstName> <LastName>Frost</LastName> <Date>1998-10-30</Date> <Organization>Lemon growers association</Organization> </item> <item source="db-11" level="1" cost="65" qry="routine 21"> <FirstName>Mike</FirstName> <LastName>Black</LastName> <Date>2006-10-30</Date> <Organization>Ford Motor Company</Organization> </item> </results> </MyRoot> 

输出产生

 <?xml version="1.0" encoding="utf-16"?> <MyNewRoot version="0.1"> <author>Employee No 321</author> <info>Alpha Bravo</info> <item cost="33" origin="www" level="77"> <GivenName>Jack</GivenName> <FamilyName>Frost</FamilyName> <Date>1998-10-30</Date> <Organization>Lemon growers association</Organization> </item> <item cost="65" qry="routine 21" origin="db-11" level="77"> <GivenName>Mike</GivenName> <FamilyName>Black</FamilyName> <Date>2006-10-30</Date> <Organization>Ford Motor Company</Organization> </item> </MyNewRoot> 

XSL脚本

 <?xml version='1.0'?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="#default"> <xsl:template match="MyRoot"> <xsl:call-template name="MainTemplate"> </xsl:call-template> </xsl:template> <xsl:template name="MainTemplate"> <MyNewRoot version="0.1"> <xsl:copy-of select="results/author" /> <xsl:copy-of select="results/info" /> <xsl:for-each select="results/item"> <xsl:call-template name="FixItemElement"/> </xsl:for-each> </MyNewRoot> </xsl:template> <xsl:template name="FixItemElement"> <xsl:copy> <xsl:copy-of select="@*[not(name()='source' or name()='level')]" /> <xsl:attribute name="origin"> <xsl:value-of select="@source"/> </xsl:attribute> <xsl:attribute name="level"> <xsl:value-of select="77"/> </xsl:attribute> <xsl:for-each select="descendant::*"> <xsl:choose> <xsl:when test="local-name(.) = 'FirstName'"> <GivenName> <xsl:value-of select="."/> </GivenName> </xsl:when> <xsl:when test="local-name(.) = 'LastName'"> <FamilyName> <xsl:value-of select="."/> </FamilyName> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:copy> </xsl:template>