我正在尝试编写一个c#.net应用程序以匹配两个XML,并使第一个文件中存在的节点与第二个XML文件匹配。
第一个XML包含比模板XML文档更多的节点。我试图将它们都匹配,并从源节点获取模板XML中存在的节点。以下是示例XML文件。
XML示例文件1
<document>
<node1>
<subnode11>
<subnode111 text="subnode">
</subnode111>
<subnode112 text="subnode">
</subnode112>
</subnode11>
</node1>
<node2>
<subnode11>
<subnode111 text="subnode">
</subnode111>
<subnode112 text="subnode">
</subnode112>
</subnode11>
</node2>
<node3>
<subnode11>
<subnode111 text="subnode">
</subnode111>
<subnode112 text="subnode">
</subnode112>
</subnode11>
</node3>
<node4>
<subnode11>
<subnode111 text="subnode">
</subnode111>
<subnode112 text="subnode">
</subnode112>
</subnode11>
</node4>
<node5>
<subnode11>
<subnode111 text="subnode">
</subnode111>
<subnode112 text="subnode">
</subnode112>
</subnode11>
</node5>
XML参考文件2
<template>
<node2>
<subnode11>
<subnode111 text="subnode">
</subnode111>
<subnode112 text="subnode">
</subnode112>
</subnode11>
</node2>
<node4>
<subnode11>
<subnode111 text="subnode">
</subnode111>
<subnode112 text="subnode">
</subnode112>
</subnode11>
</node4>
所需的输出是
<document>
<node2>
<subnode11>
<subnode111 text="subnode">
</subnode111>
<subnode112 text="subnode">
</subnode112>
</subnode11>
</node2>
<node4>
<subnode11>
<subnode111 text="subnode">
</subnode111>
<subnode112 text="subnode">
</subnode112>
</subnode11>
</node4>
下面是我用C#编写的内容。
if (!string.IsNullOrEmpty(xmlTemplateFilePathLocation))
{
string[] filePaths = Directory.GetFiles(xmlTemplateFilePathLocation, "*.xml");
foreach (string xmlFile in filePaths)
{
uniqueFileName = Path.GetFileNameWithoutExtension(xmlFile);
string xmlContent = File.ReadAllText(xmlFile);
if (!IsValidXmlString(xmlContent))
{
xmlContent = RemoveInvalidXmlChars(xmlContent);
}
if (IsValidXmlString(xmlContent))
{
File.WriteAllText(xmlFile, xmlContent);
}
string xsltTextString = string.Empty;
xsltTextString = xsltTextString + "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:ns=\"some:ns\">";
xsltTextString = xsltTextString + "<xsl:output omit-xml-declaration=\"yes\" indent=\"yes\"/>";
xsltTextString = xsltTextString + "<xsl:strip-space elements=\"*\"/>";
xsltTextString = xsltTextString + "<ns:WhiteList>";
Dictionary<string, List<int>> nodeTable = new Dictionary<string, List<int>>();
using (XmlReader reader = XmlReader.Create(xmlFile))
{
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element)
{
if (!nodeTable.ContainsKey(reader.LocalName))
{
nodeTable.Add(reader.LocalName, new List<int>(new int[] { reader.Depth }));
}
else if (!nodeTable[reader.LocalName].Contains(reader.Depth))
{
nodeTable[reader.LocalName].Add(reader.Depth);
}
}
reader.Read();
}
}
foreach (KeyValuePair<string, List<int>> kv in nodeTable)
{
if (kv.Value.Count == 1 && kv.Value[0] == 1 )
{
xsltTextString = xsltTextString + "<name>" + kv.Key + "</name>";
}
for (int i = 0; i < kv.Value.Count; i++)
{
if (i < kv.Value.Count - 1)
{
//Console.Write("{0}, ", kv.Value[i]);
}
else
{
//Console.WriteLine(kv.Value[i]);
xsltTextString = xsltTextString + "<name>" + kv.Value[i] + "</name>";
}
}
}
xsltTextString = xsltTextString + "</ns:WhiteList>";
xsltTextString = xsltTextString + "<xsl:template match = \"node()|@*\">";
xsltTextString = xsltTextString + "<xsl:copy>";
xsltTextString = xsltTextString + "<xsl:apply-templates select = \"node()|@*\"/>";
xsltTextString = xsltTextString + "</xsl:copy>";
xsltTextString = xsltTextString + "</xsl:template>";
xsltTextString = xsltTextString + "<xsl:template match=\"*[not(descendant-or-self::*[name()=document('')/*/ns:WhiteList/*])]\"/>";
xsltTextString = xsltTextString + "</xsl:stylesheet>";
//transforming the xml file with the generated XSLT
StringBuilder htmlOutput = new StringBuilder();
TextWriter htmlWriter = new StringWriter(htmlOutput);
File.WriteAllText(xmlTemplateFilePathLocation + uniqueFileName + ".xslt", xsltTextString);
XslCompiledTransform objXSLTransform = new XslCompiledTransform();
objXSLTransform.Load(xmlTemplateFilePathLocation + uniqueFileName + ".xslt", new XsltSettings { EnableDocumentFunction = true }, new XmlUrlResolver());
string xmlFilexml = "C:\\Desktop\\Test\\XML\\722033_1004_2.XML";
XmlReader readerXML = XmlReader.Create(xmlFilexml);
objXSLTransform.Transform(readerXML, null, htmlWriter);
htmlContent = htmlWriter.ToString();
Console.WriteLine(htmlContent);
使用当前代码,我只能提取主节点,而不能提取子节点。我还需要在输出中获取子节点。
如果父节点匹配,则将它们视为匹配项。 Node2和Node4与模板XML匹配,并且应该与源XML的子节点一起出现在输出XML中。
我正在使用XSLT 1.0,最终输出将为HTML。
谢谢。