【问题标题】:XSLT transform using TXMLDocument使用 TXMLDocument 进行 XSLT 转换
【发布时间】:2018-01-23 23:05:42
【问题描述】:

我尝试使用 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 转换的正确解决方案是什么?

【问题讨论】:

  • 我不知道您使用的 API,但 XML.DocumentElement.TransformNode(XSL.DocumentElement, Output) 似乎是明确尝试使用根元素(例如您的示例中的 notelist)而不是文档节点 @987654329 开始转换@ 并且在这种情况下,您的样式表确实不会输出任何内容。因此,如果您使用的 API 允许您直接在 XML 上调用 TransformNode,我建议您分别尝试另一种方法来在文档节点而不是根元素上运行转换。

标签: xml delphi xslt msxml xmldom


【解决方案1】:

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-15
  • 2014-06-14
  • 2012-09-30
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多