在C#中使用具有默认命名空间的Xpath进行规范化 [英] Using Xpath With Default Namespace in C# for Canonicalisation

查看:78
本文介绍了在C#中使用具有默认命名空间的Xpath进行规范化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将C14N转换应用于某些生成的XML.看来我无法使用LINQ来检索节点以执行规范化,因此我不得不对DOM进行老套",但我认为我对默认名称空间不满意.

I'm trying to apply the C14N transform to some generated XML. It appears I can't use LINQ to retrieve the nodes to perform the canonicalisation so I have to go 'old school' with the DOM but I think I'm falling foul of the default namespace.

这是我的代码的示例.

static void Main(string[] args)
{
    XmlDocument xDoc = new XmlDocument();

    // Load some test xml
    string path = @"..\..\TestFiles\Test_1.xml";
    if (File.Exists(path) == true)
    { 
        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 in books.xml to the XmlNamespaceManager.
    xmlnsManager.AddNamespace("", "http://www.myApps.co.uk/");

    // Create a list of nodes to have the Canonical treatment
        //Execute the XPath query using the SelectNodes method of the XmlDocument.
        //Supply the XmlNamespaceManager as the nsmgr parameter.
        //The matching nodes will be returned as an XmlNodeList.
    XmlNodeList nodeList = xDoc.SelectNodes("/ApplicationsBatch/Applications|/ApplicationsBatch/Applications//*", xmlnsManager);

    // Perform the C14N transform on the data
    XmlDsigC14NTransform transform = new XmlDsigC14NTransform();

    transform.LoadInput(nodeList);
    MemoryStream ms = (MemoryStream)transform.GetOutput(typeof(Stream));

    File.WriteAllBytes(@"..\..\TestFiles\ModifiedTest_1", ms.ToArray());
}

还有我的XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<ApplicationsBatch xmlns="http://www.myApps.co.uk/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <MessageHeader>
    <MessageID>00000003</MessageID>
    <Body>11223344556</Body>
    <Timestamp>2011-08-02T09:00:00</Timestamp>
    <MessageCheck>?</MessageCheck>
  </MessageHeader>
  <Applications>
    <Application>
      <ApplicantDetails>
        <Title>MR</Title>
        <Forename>HOMER</Forename>
        <Middlenames>
          <Middlename></Middlename>
        </Middlenames>
        <PresentSurname>SIMPSON</PresentSurname>
        <CurrentAddress>
          <Address>
            <AddressLine1>ADDRESS LINE1</AddressLine1>
            <AddressLine2>ADDRESS LINE2</AddressLine2>
            <AddressTown>ADDRESS Town</AddressTown>
            <AddressCounty>COUNTY</AddressCounty>
            <Postcode>POST CODE</Postcode>
            <CountryCode>GB</CountryCode>
          </Address>
          <ResidentFromGyearMonth>2007-01</ResidentFromGyearMonth>
        </CurrentAddress>
      </ApplicantDetails>
    </Application>
    <Application>
      <ApplicantDetails>
        <Title>MR</Title>
        <Forename>BART</Forename>
        <Middlenames>
          <Middlename></Middlename>
        </Middlenames>
        <PresentSurname>SIMPSON</PresentSurname>
        <CurrentAddress>
          <Address>
            <AddressLine1>ADDRESS LINE1</AddressLine1>
            <AddressLine2>ADDRESS LINE2</AddressLine2>
            <AddressTown>ADDRESS Town</AddressTown>
            <AddressCounty>COUNTY</AddressCounty>
            <Postcode>POST CODE</Postcode>
            <CountryCode>GB</CountryCode>
          </Address>
          <ResidentFromGyearMonth>2007-01</ResidentFromGyearMonth>
        </CurrentAddress>
      </ApplicantDetails>
    </Application>
  </Applications>
</ApplicationsBatch>

我已经阅读了该地区的其他一些主题,并遇到了这个宝石,但是并不能解决问题.

I've read a few other topics around the area and came across this Gem but it's not solved the problem.

使用XPath Visualiser显示应该选择所需的节点,但是我的代码无法选择任何节点.

Using the XPath Visualiser shows the required nodes should be selected but my code fails to select any.

推荐答案

我已经找到了解决我问题的部分答案.

I've found a partial answer to my problem.

将新名称空间添加到管理器后,默认名称空间不能为空字符串. 这就是我最终得到的:

When a new namespace is added to the manager it appears that the default namespace can't be an empty string. This is what I ended up with:

//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/");

然后我需要修改XPath以反映名称空间标识符,如下所示:

I then needed to modify the XPath to reflect the namespace identifier like this:

// Create a list of nodes to have the Canonical treatment
    //Execute the XPath query using the SelectNodes method of the XmlDocument.
    //Supply the XmlNamespaceManager as the nsmgr parameter.
    //The matching nodes will be returned as an XmlNodeList.
XmlNodeList nodeList = xDoc.SelectNodes("/x:ApplicationsBatch/x:Applications|/x:ApplicationsBatch/x:Applications//*", xmlnsManager);

现在已选择节点并准备好进行转换……尽管它返回了XML的正确结构,但是所有值都已删除,但这是另一个问题.

The nodes are now selected and ready for transformation... although that returns the correct structure of XML but all the values have been removed but that is a problem for another question.

这篇关于在C#中使用具有默认命名空间的Xpath进行规范化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆