Внесение изменений в XSLT с использованием XmlDocument, XmlNamespaceManager, префикс не сохранен - PullRequest
1 голос
/ 20 января 2011

Я пишу функцию, которая принимает набор данных и выводит Excel-XML (http://msdn.microsoft.com/en-us/library/aa140066(v=office.10).aspx)

Чтобы поля Datetime и integer не обрабатывались как строки, я пытаюсь отредактировать XLST с помощью класса XmlDocument. Я хочу добавить что-то вроде этого:

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

в шаблон

РЕДАКТИРОВАТЬ: Код сейчас на http://pastebin.com/r2Rea4Jw

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

ПРОБЛЕМА Xsl: value-of теряет свой префикс xsl: в выводе, тогда как ss: DataType выводится нормально.

Ответы [ 2 ]

2 голосов
/ 20 января 2011

Использование 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>
0 голосов
/ 21 января 2011

Решение на данный момент:

  1. Использование XmlNamespaceManager
  2. Измените local-name () на имя поля, поскольку шаблон теперь находится на уровне строки, а не ячейки.
  3. addЭлемент «Cell», использующий те же базовые xmlns, что и корневой элемент, чтобы избежать xmlns = ""
  4. Захват промежуточных форм каждого XMLDocument для отладки ...
...