XML Canonicalization在转换后的输出中返回空元素

时间:2011-08-03 09:58:59

标签: c# xml canonicalization

我有related post询问如何使用XPath语句从XmlDocument中选择节点。

我可以让SelectNodes工作的唯一方法是创建一个非默认命名空间“x”,然后显式引用XPath语句中的节点。

虽然这可以工作并为我提供节点列表,但规范化却无法为输出中的所选节点生成任何内容。

我尝试过使用XmlDsigExcC14NTransform并指定命名空间,但这会产生相同的输出。

下面是生成的xml输出示例(使用我related post中的XML):

<Applications xmlns="http://www.myApps.co.uk/">
  <Application>
    <ApplicantDetails>
      <Title>
      </Title>
      <Forename>
      </Forename>
      <Middlenames>
        <Middlename>
        </Middlename>
      </Middlenames>
      <PresentSurname>
      </PresentSurname>
      <CurrentAddress>
        <Address>
          <AddressLine1>
          </AddressLine1>
          <AddressLine2>
          </AddressLine2>
          <AddressTown>
          </AddressTown>
          <AddressCounty>
          </AddressCounty>
          <Postcode>
          </Postcode>
          <CountryCode>
          </CountryCode>
        </Address>
        <ResidentFromGyearMonth>
        </ResidentFromGyearMonth>
      </CurrentAddress>
    </ApplicantDetails>
  </Application>
  <Application>
    <ApplicantDetails>
      <Title>
      </Title>
      <Forename>
      </Forename>
      <Middlenames>
        <Middlename>
        </Middlename>
      </Middlenames>
      <PresentSurname>
      </PresentSurname>
      <CurrentAddress>
        <Address>
          <AddressLine1>
          </AddressLine1>
          <AddressLine2>
          </AddressLine2>
          <AddressTown>
          </AddressTown>
          <AddressCounty>
          </AddressCounty>
          <Postcode>
          </Postcode>
          <CountryCode>
          </CountryCode>
        </Address>
        <ResidentFromGyearMonth>
        </ResidentFromGyearMonth>
      </CurrentAddress>
    </ApplicantDetails>
  </Application>
</Applications>

1 个答案:

答案 0 :(得分:2)

另一个StackOverflow用户有一个similar problem here

使用这个新代码,我发现结果会有所不同,具体取决于您如何将节点传递给LoadInput方法。实现下面的代码有效。

我仍然很好奇为什么它以某种方式工作而不是另一种方式,但会在未雨绸缪的情况下保留

static void Main(string[] args)
{
    string path = @"..\..\TestFiles\Test_1.xml";
    if (File.Exists(path) == true)
    {
        XmlDocument xDoc = new XmlDocument();
        xDoc.PreserveWhitespace = true;
        using (FileStream fs = new FileStream(path, FileMode.Open))
        {
            xDoc.Load(fs);
        }

        //Instantiate an XmlNamespaceManager object. 
        System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(xDoc.NameTable);

        //Add the namespaces used to the XmlNamespaceManager.
        xmlnsManager.AddNamespace("x", "http://www.myApps.co.uk/");

        // Create a list of nodes to have the Canonical treatment
        XmlNodeList nodeList = xDoc.SelectNodes("/x:ApplicationsBatch/x:Applications|/x:ApplicationsBatch/x:Applications//*", xmlnsManager);

        //Initialise the stream to read the node list
        MemoryStream nodeStream = new MemoryStream();
        XmlWriter xw = XmlWriter.Create(nodeStream);
        nodeList[0].WriteTo(xw);
        xw.Flush();
        nodeStream.Position = 0;

        // Perform the C14N transform on the nodes in the stream
        XmlDsigC14NTransform transform = new XmlDsigC14NTransform();
        transform.LoadInput(nodeStream);

        // use a new memory stream for output of the transformed xml 
        // this could be done numerous ways if you don't wish to use a memory stream
        MemoryStream outputStream = (MemoryStream)transform.GetOutput(typeof(Stream));
        File.WriteAllBytes(@"..\..\TestFiles\CleanTest_1.xml", outputStream.ToArray());
    }
}