c# - 我正在尝试匹配两个 xml 文件并从第一个文件中获取 xml 节点作为输出 xml
问题描述
我正在尝试编写 ac#.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。
提前致谢。
解决方案
推荐阅读
- selenium - Selenium C# 如何找到正确的框架来关注并找到元素?
- r - 对 MCA 对象 FactoMineR 进行预测时出错
- neo4j - 如何创建一个值为 count() 的节点?
- python - pandas iterrows() 跳过指定的行
- promise - 在 FeathersJS 中,find() 的钩子无法正常工作
- asynchronous - 在 Flutter 中获取 Firebase 用户 ID 时,共享首选项在启动时返回 null
- c - 当键入 'B' 或 'b' 时,使用 continue 将不计算在内
- google-sheets - 突出显示额外行的条件格式
- php - 登录 cookie 问题后的 PHP 7.2 MySQL Google App Engine
- python - 我的电脑有一个 python 2.7 控制台,我想把它转换成 python 3?我怎样才能在没有(或更少)删除的情况下做到这一点?