Delphi MSXML-名称空间信息未持久化

Delphi MSXML-名称空间信息未持久化,delphi,msxml,xslt,Delphi,Msxml,Xslt,我正在使用MSXML6.0将我自己的XML转换为另一种XML格式。我不确定我是否只是不明白MSXML是如何工作的,但我相信我已经注意到了它的一些奇怪行为 我正在使用以下方法将名称空间添加到我的XML文档中: XmlDocument.setProperty('SelectionNamespaces', ' xmlns:ms=''http://mydomain.com/2010/MySchema'''); 然后,我在内存中使用自己的自定义序列化程序构建XML(而不是保存到磁盘)。序列化后,我将加载

我正在使用MSXML6.0将我自己的XML转换为另一种XML格式。我不确定我是否只是不明白MSXML是如何工作的,但我相信我已经注意到了它的一些奇怪行为

我正在使用以下方法将名称空间添加到我的XML文档中:

XmlDocument.setProperty('SelectionNamespaces',
' xmlns:ms=''http://mydomain.com/2010/MySchema''');
然后,我在内存中使用自己的自定义序列化程序构建XML(而不是保存到磁盘)。序列化后,我将加载XSLT文件并使用

问题是转换正在工作,但其中没有与XPath匹配的特定模板。我通过VisualStudio使用测试数据运行XSLT文件,消除了XSLT文件本身的任何问题,并且它按预期工作。然后我假设这一定是一个编码问题,所以我确保所有涉及的文档都是以UTF-8的形式读/写出来的……仍然没有运气

下面是变换的示例:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ms="http://mydomain.com/2010/MySchema" exclude-result-prefixes="ms">
<xsl:template match="/">
<ARoot>      
  <head>
    <xsl:apply-templates select="ms:Element/ms:SubElement" />
  </head>
  <body>
    <xsl:apply-templates select="ms:Element/ms:DifferentSubElement" />
  </body>
</ARoot>

因此,当运行MSXML时,转换的结果会带来基本结构,但不包括任何模板数据。经过一些测试,我发现让它工作的唯一方法是按以下步骤进行:

  • 创建新的XML文档
  • 使用
    setProperty
  • 序列化XML并保存到磁盘
  • 关闭文档-额外步骤
  • 创建新的Xml文档-额外步骤
  • 重新加载文档-额外步骤
  • 重新设置名称空间信息-额外步骤
  • 执行转换
  • 所以MSXML似乎在某个点上丢失了名称空间信息。更奇怪的是,即使重置名称空间信息(序列化后)并尝试转换,它仍然无法工作!只有在保存文档、关闭文档并重新创建一个新的XML文档并将其加载回(因此我需要重置名称空间)时,它才会起作用

    有人对此有什么想法吗?

    用于XPath和selectNodes和selectSingleNode方法,而不是用于XSLT或其他目的。因此,我不知道为什么要设置它,以及您希望它有什么帮助,因为您似乎没有使用selectNodes或selectSingleNode。
    您希望用MSXML 6实现什么?如果您想创建一些MSXML DOM文档,其中包含名称空间中的元素和/或属性,那么请确保使用createNode,因为这是MSXML API中唯一支持名称空间的方法。

    MSXML是旧的->神秘的。你的代码平台是什么?@annakata:platform是Win32,使用Delphi 2010。代码需要关闭。我认为有MSXML方法来设置名称空间(而不是setProperty)。然后,要将节点添加到DOM中,请使用具有附加名称空间参数的重载MSXML方法。@mjustin:从我看到的
    setProperty
    是唯一的方法吗?请参阅@Martin答案上的MSDN链接。无论如何,这不是问题所在……我有自己的自定义XML,它有自己的模式。当我写出XML格式时,我的元素名将包含模式的前缀,例如
    ms:element
    。因此,要使XML文档有效,它必须包含名称空间。至于包含它的XSLT…如果我在执行XPath时没有指定名称空间,那么它就不匹配任何内容。我一开始不太理解您所指的内容。在对代码进行了一些重构之后,我明白了哪里出了问题。当我使用
    createElement
    /
    createAttribute
    创建节点时,这是名称空间无关的,即这些节点不会映射到任何特定的名称空间。按照您的建议,将我的序列化程序更改为使用
    createNode
    。谢谢
    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ms="http://mydomain.com/2010/MySchema" exclude-result-prefixes="ms">
    <xsl:template match="/">
    <ARoot>      
      <head>
        <xsl:apply-templates select="ms:Element/ms:SubElement" />
      </head>
      <body>
        <xsl:apply-templates select="ms:Element/ms:DifferentSubElement" />
      </body>
    </ARoot>