使用XmlDocument修改XSLT,XmlNamespaceManager,前缀未保留

时间:2011-01-20 12:30:36

标签: .net xml xslt xmldocument xml-namespaces

我正在编写一个接受数据集并输出Excel-XML(http://msdn.microsoft.com/en-us/library/aa140066(v=office.10).aspx)的函数

为了确保日期时间和整数字段不被视为字符串,我正在尝试使用XmlDocument类编辑XLST。我想添加这样的东西:

<Cell>
    <Data ss:Type="String">
        <xsl:value-of select="local-name()"/>
    </Data>
</Cell>

到与每行匹配的&lt; xsl:模板。

编辑:现在代码在 http://pastebin.com/r2Rea4Jw

Excel.xsl http://pastebin.com/abkKCPmh

问题 xsl:value-of在输出中丢失其xsl:前缀,而ss:DataType输出正常。

2 个答案:

答案 0 :(得分:2)

使用http://msdn.microsoft.com/en-us/library/c22k3d47.aspx,例如xDoc.createElement("xsl", "value-of", "http://www.w3.org/1999/XSL/Transform")如果要创建XSLT xsl:value-of元素节点。

[edit]对我来说,重载工作正常,给你更完整的例子,当XMLFile1.xml

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0"
                xmlns="urn:schemas-microsoft-com:office:spreadsheet"
                xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/*/*">
    <Row/>
  </xsl:template>

</xsl:stylesheet>

然后是以下C#代码

    XmlDocument sheet = new XmlDocument();
    sheet.Load(@"..\..\XMLFile1.xml");
    sheet.Save(Console.Out);
    Console.WriteLine();

    const string ss = "urn:schemas-microsoft-com:office:spreadsheet";
    const string xsl = "http://www.w3.org/1999/XSL/Transform";

    XmlNamespaceManager mgr = new XmlNamespaceManager(sheet.NameTable);
    mgr.AddNamespace("ss", ss);
    mgr.AddNamespace("xsl", xsl);

    XmlNode row = sheet.SelectSingleNode("/xsl:stylesheet/xsl:template[@match = '/*/*']/ss:Row", mgr);
    Console.WriteLine(row.OuterXml);

    XmlNode cell = row.AppendChild(sheet.CreateElement("Cell", ss));

    XmlNode data = cell.AppendChild(sheet.CreateElement("Data", ss));
    XmlAttribute type = sheet.CreateAttribute("ss", "Type", ss);
    type.Value = "String";
    data.Attributes.Append(type);

    XmlElement valueOf = data.AppendChild(sheet.CreateElement("xsl", "value-of", xsl)) as XmlElement;
    valueOf.SetAttribute("select", "local-name()");

    sheet.Save(Console.Out);
    Console.WriteLine();

    XslCompiledTransform proc = new XslCompiledTransform();
    proc.Load(sheet);

编译并运行得很好并输出

<?xml version="1.0" encoding="ibm850"?>
<xsl:stylesheet version="1.0" xmlns="urn:schemas-microsoft-com:office:spreadshee
t" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/*/*">
    <Row />
  </xsl:template>
</xsl:stylesheet>
<Row xmlns="urn:schemas-microsoft-com:office:spreadsheet" />
<?xml version="1.0" encoding="ibm850"?>
<xsl:stylesheet version="1.0" xmlns="urn:schemas-microsoft-com:office:spreadshee
t" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/*/*">
    <Row>
      <Cell>
        <Data ss:Type="String">
          <xsl:value-of select="local-name()" />
        </Data>
      </Cell>
    </Row>
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

到目前为止的解决方案:

  1. 使用XmlNamespaceManager
  2. 将local-name()更改为字段名称,因为模板现在位于行级而不是单元格。
  3. 使用相同的基本xmlns作为根元素添加“Cell”元素,以避免xmlns =“”
  4. 捕获每个XMLDocument的中间形式以进行调试......