1

我有一篇相关的帖子询问如何使用 XPath 语句从 XmlDocument 中选择节点。

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

虽然这可行并为我提供了一个节点列表,但规范化随后无法为输出中我选择的节点生成任何内容。

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

下面是生成的 xml 输出示例(使用我相关帖子中的 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>
4

1 回答 1

2

另一个 StackOverflow 用户在这里遇到了类似的问题

玩弄这个新代码,我发现结果会有所不同,具体取决于您将节点传递到 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());
    }
}
于 2011-08-04T15:03:01.937 回答