在c#中使用带有默认名称空间的Xpath进行规范化
本文关键字:空间 Xpath 规范化 行规 默认 | 更新日期: 2023-09-27 18:04:19
我试图将C14N转换应用于一些生成的XML。看来我不能使用LINQ来检索节点来执行规范化,所以我必须用DOM去"老派",但我认为我正在与默认命名空间发生冲突。
下面是我的代码示例。
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());
}
And my 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>
我已经阅读了该地区的其他一些主题,并遇到了这个宝石,但它并没有解决问题。
使用XPath Visualiser显示应该选择所需的节点,但我的代码未能选择任何节点。
我找到了我问题的部分答案。
当一个新的命名空间被添加到管理器时,默认的命名空间似乎不能是一个空字符串。这就是我最后的结果:
//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以反映名称空间标识符,如下所示:
// 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结构,但所有的值都被删除了,但这是另一个问题的问题。