我正在尝试匹配两个xml文件并从第一个文件获取xml节点作为输出xml

时间:2018-12-19 19:14:39

标签: c# xml compare xslt-1.0 xmldocument

我正在尝试编写一个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。

谢谢。

0 个答案:

没有答案