使用[MS] XSLT脚本修改XML节点

时间:2009-09-13 12:35:13

标签: windows xml xslt scripting

我想选择一个节点并使用一个修改其属性和子节点 xsl:脚本函数。此外,匹配该节点的子节点的模板应该 STILL执行他们的工作(脚本完成处理节点后)。

  1. 可以使用XSLT完成吗?
  2. 你能为这种转变提供一个例子/骨架吗?

1 个答案:

答案 0 :(得分:1)

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

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

  • 根元素名称和属性
  • 通过从层次结构中删除元素来展平
  • 删除结果/日期元素
  • 重命名项目的'source'属性'origin'
  • 更改项目的“级别”属性值
  • 重命名item元素的FirstName和LastName元素

示例输入

<?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>