使用XSLT的XML到XML

时间:2009-05-21 02:37:59

标签: html xml xslt

我正在尝试使用XSL从现有的XML文件创建一个新的XML文件。在编写新文件时,我想屏蔽出现在accountname字段中的数据。

这就是我的XML的样子:

<?xml version="1.0" encoding="UTF-8"?>
<Sumit>
    <AccountName>Sumit</AccountName>
      <CCT_datasetT id="Table">
       <row>
         <CCTTitle2>Title</CCTTitle2>
       </row>
       </CCT_datasetT>
</Sumit>

这是我的XSL代码:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="no" />

  <xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

  <xsl:template match="@*">
    <xsl:attribute namespace="{namespace-uri()}" name="{name()}"/>
  </xsl:template>

<xsl:template match="AccountName">
<AccountName>acc_no</AccountName>
</xsl:template>

</xsl:stylesheet>

当我将XSL代码应用于我的XML时,我得到以下输出:

<?xml version="1.0" encoding="UTF-16"?>
<Sumit>
<AccountName>acc_no</AccountName>
<CCT_datasetT id="">
<row>
<CCTTitle2>Title</CCTTitle2>
</row>
</CCT_datasetT>
</Sumit>

有以下问题:

1)它使用UTF-16编码

创建输出

2)第二行的输出是:

<CCT_datasetT id="">

缺少属性值(表)。

任何人都可以告诉我如何摆脱这两个问题。非常感谢。


@Evan Lenz:

以下是javascript代码:

var oArgs = WScript.Arguments;

if (oArgs.length == 0)
{
   WScript.Echo ("Usage : cscript xslt.js xml xsl");
   WScript.Quit();
}
xmlFile = oArgs(0) + ".xml";
xslFile = oArgs(1) + ".xsl";


var xml = new ActiveXObject("Microsoft.XMLDOM")
xml.async = false
xml.load(xmlFile)

// Load the XSL
var xsl = new ActiveXObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load(xslFile)

// Transform
var msg = xml.transformNode(xsl)



var fso = new ActiveXObject("Scripting.FileSystemObject");



// Open the text file at the specified location with write mode

var txtFile = fso.OpenTextFile("Output.xml", 2, false, 0);

txtFile.Write(msg);
txtFile.close();

它在新文件“Output.xml”中创建输出,但我不知道为什么编码会发生变化。由于以下原因,我更关心它:

我的输入XML包含以下代码:

<Status></Status>

在输出中它显示为

<Status>
</Section>

为所有空标记引入了回车符。我不确定,如果它与编码有关。请建议。

非常感谢。

2 个答案:

答案 0 :(得分:1)

删除第二个模板规则。第一个模板规则(标识规则)将为您复制属性。通过包含第二个(具有显式<xsl:attribute>指令),您将创建冲突 - 错误条件,并且XSLT处理器正在通过选择样式表中稍后的那个来恢复。 “id”属性为空的原因是您的第二条规则是创建一个具有相同名称但没有值的新属性。但是,无论如何,第二条规则是不必要的,所以你应该删除它。这将解决遗失的属性值问题。

对于输出编码,听起来你的XSLT处理器没有遵守你给它的<xsl:output>指令,或者它是在上下文(例如服务器端框架?)中调用的,其中编码由框架决定,而不是XSLT代码。您使用的XSLT处理器是什么以及如何调用它?

更新(re:字符编码):

save Method (DOMDocument)文档说明了这一点:

  

字符编码基于XML声明中的编码属性,例如<?xml version="1.0" encoding="windows-1252"?>。如果未指定编码属性,则默认设置为UTF-8。

我会尝试使用transformNodeToObject()和save()而不是输出到字符串。

我没有测试过这个,但你可能想要这样的东西:

var result = new ActiveXObject("Microsoft.XMLDOM")

// Transform
xml.transformNodeToObject(xsl, result);

result.save("Output.xml");

更新(re:不需要的空格):

如果您希望最终控制结果中出现的空格,则不应在<xsl:output>元素上指定indent =“yes”。尝试删除它。

答案 1 :(得分:1)

试试这个:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="no" />

    <xsl:template match="@*|node()">
      <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
  </xsl:template>

    <!-- You don't actually need this template -->
    <!-- but I think this was what you were trying to do -->
    <xsl:template match="@*" priority="2">
      <xsl:attribute namespace="{namespace-uri()}" name="{name()}"><xsl:value-of select="."/></xsl:attribute>
    </xsl:template>

  <xsl:template match="AccountName" priority="2">
  <AccountName>acc_no</AccountName>
  </xsl:template>

</xsl:stylesheet>

至于UTF问题,你做的是正确的。

来自www.w3.org/TR/xslt: encoding属性指定用于输出结果树的首选编码。 XSLT处理器必须遵守UTF-8和UTF-16的值。