Я пытаюсь сопоставить два файла XML и получить узлы XML из первого файла в качестве выходного XML - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь написать приложение 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.

Заранее спасибо.

...