使用TXMLDocument进行XSLT转换

时间:2018-01-23 12:10:20

标签: xml delphi xslt msxml xmldom

我试图使用TXMLDocument进行XSLT转换并发现无法解释(对我来说)行为 - TXMLDocument.transformNode不会处理' /'模式(与根节点https://msdn.microsoft.com/en-us/library/ms256113(v=vs.85).aspx匹配)。

XML:

<notelist>
  <note>NoteText</note>
</notelist>

XSLT:

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

  <xsl:template match="/">
    <TransformedNoteList>
      <xsl:apply-templates/>  
    </TransformedNoteList>
  </xsl:template>

  <xsl:template match="text()" /> 
</xsl:stylesheet>

使用TXMLDocument Delphi代码:

var
  XML: IXMLDocument;
  XSL: IXMLDocument;
  Output: XmlDomString;
begin
  ResultMemo.Clear;

  XML := LoadXMLData(XMLMemo.Text);
  XSL := LoadXMLData(XsltMemo.Text);

  XML.DocumentElement.TransformNode(XSL.DocumentElement, Output);

  ResultMemo.Text := Output;

我期待这样的结果:

<?xml version="1.0"?>
<TransformedNoteList></TransformedNoteList>

但是获得了空的xml文件。

我试图通过使用IXslProcessor重现此行为,一切正常。 有人可以解释一下使用TXMLDocument进行转换的原因,因为通过IXslProccessor无法理解吗?

使用IXSLProcessor:

var
  XMLDoc, XSLStylesheet: IXMLDOMDocument;
  XSLProcessor: IXSLProcessor;
  XSLTemplate: IXSLTemplate;
begin
  ResultMemo.Clear;

  XMLDoc := CoDOMDocument60.Create;
  XMLDoc.LoadXML(XMLMemo.Text);

  XSLStylesheet := CoDOMDocument60.Create;
  XSLStylesheet.LoadXML(XsltMemo.Text);

  XSLTemplate := CoXSLTemplate60.Create;
  XSLTemplate._Set_stylesheet(XSLStylesheet);
  XSLProcessor := XSLTemplate.createprocessor;
  XSLProcessor.Input := XMLDoc;

  if XSLProcessor.Transform then
    ResultMemo.Text := XSLProcessor.Output;
end;

XSLT转换的正确解决方案是什么?

1 个答案:

答案 0 :(得分:2)

正如Martin所说,match="/"匹配树中的顶级节点(DOM和XPath 2.0称之为文档节点,XPath 1.0将其称为根节点)。但是你已经通过提供树中最外层的元素来开始转换(DOM称之为文档元素)。要匹配最外面的元素,您需要模式match="/*"