Подтвердить что ты не робот

Каков самый быстрый способ объединить два xml файла в один

Если у меня есть две строки xml1 и xml2, которые оба представляют xml в том же формате. Каков самый быстрый способ объединить их? Формат не важен, но я просто хочу знать, как я могу избавиться или?

xml1:

<?xml version="1.0" encoding="utf-8"?>
<AllNodes>
   <NodeA>
      <NodeB>test1</NodeB>
      <NodeB>test2</NodeB>
   </NodeA>
</AllNodes>

xm2:

<?xml version="1.0" encoding="utf-8"?>
<AllNodes>
   <NodeA>
      <NodeB>test6</NodeB>
      <NodeB>test7</NodeB>
   </NodeA>
   <NodeA>
      <NodeB>test99</NodeB>
      <NodeB>test23</NodeB>
   </NodeA>
</AllNodes>

и что-то вроде этого:

<?xml version="1.0" encoding="utf-8"?>
    <AllNodes>
          <NodeA>
              <NodeB>test1</NodeB>
              <NodeB>test2</NodeB>
          </NodeA>
         <NodeA>
              <NodeB>test6</NodeB>
              <NodeB>test7</NodeB>
           </NodeA>
           <NodeA>
              <NodeB>test99</NodeB>
              <NodeB>test23</NodeB>
           </NodeA>
    </AllNodes>
4b9b3361

Ответ 1

Самый простой способ сделать это - использовать LINQ to XML. Вы можете использовать Union или Concat в зависимости от ваших потребностей.

var xml1 = XDocument.Load("file1.xml");
var xml2 = XDocument.Load("file2.xml");

//Combine and remove duplicates
var combinedUnique = xml1.Descendants("AllNodes")
                          .Union(xml2.Descendants("AllNodes"));

//Combine and keep duplicates
var combinedWithDups = xml1.Descendants("AllNodes")
                           .Concat(xml2.Descendants("AllNodes"));

Ответ 2

Преобразование XSLT могло бы сделать это:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:param name="pXml1" select="''" />
  <xsl:param name="pXml2" select="''" />
  <xsl:param name="pRoot" select="'root'" />

  <xsl:template match="/">
    <xsl:variable name="vXml1" select="document($pXml1)" />
    <xsl:variable name="vXml2" select="document($pXml2)" />

    <xsl:element name="{$pRoot}">
      <xsl:copy-of select="$vXml1/*/*" />
      <xsl:copy-of select="$vXml2/*/*" />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

Передайте имена файлов в качестве параметров, а также имя нового корневого элемента.

Применить к любому XML-документу, например. пустой.

Ответ 3

Это самый быстрый и чистый способ слияния XML файлов.

XElement xFileRoot = XElement.Load(file1.xml);
XElement xFileChild = XElement.Load(file2.xml);
xFileRoot.Add(xFileChild);
xFileRoot.Save(file1.xml);

Ответ 4

Если вы можете гарантировать этот формат, вы можете объединить их, выполнив строковые манипуляции:

  • Прочитайте первый файл, сохраните все до "</AllNodes> "
  • Прочитайте второй файл, удалите часть до "<AllNodes> "
  • Объедините эти строки.

Это должно быть самым быстрым способом, поскольку не требуется синтаксический анализ.

const string RelevantTag = "AllNodes";

string xml1 = File.ReadAllText(xmlFile1);
xml1 = xml1.Substring(0, xml.LastIndexOf("</" + RelevantTag + ">"));

string xml2 = File.ReadAllText(xmlFile2);
xml2 = xml2.Substring(xml.IndexOf("<" + RelevantTag + ">") + "<" + RelevantTag + ">".Length, xml1.Length);

File.WriteAllText(xmlFileCombined, xm1 + xml2);

Это говорит, что я всегда предпочитаю безопасный путь к быстрому пути.

Ответ 5

У вас есть два основных варианта:

  • Разберите xml, объедините структуры данных, сериализуйте обратно в xml.

  • Если вы знаете структуру, используйте некоторые основные манипуляции с строкой, чтобы взломать ее. Например, в приведенном выше примере вы можете взять внутри allnodes в двух блоках xml и поместить их в один блок allnodes и сделать.

Ответ 6

Если вы хотите использовать XmlDocument, попробуйте это

 var lNode = lDoc1.ImportNode(lDoc2.DocumentElement.FirstChild, true);
 lDoc1.DocumentElement.AppendChild(lNode);

Ответ 7

Лучшее решение для меня, основано на ответе Хосе Базилио, слегка изменено,

var combinedUnique = xml1.Descendants()
    .Union(xml2.Descendants());
combinedUnique.First().Save(#fullName)

Ответ 8

Если бы я это делал (используя С#), я бы создал класс, в котором я мог бы десериализовать этот XML (вы можете использовать xsd.exe для этого), а затем пропустите все узлы в объекте, представляющем первый кусок XML и "Добавить" их в свойство AllNodes объекта, представляющего второй XML.

Затем сериализуйте второй класс обратно из XML, и он должен выглядеть как ваш третий пример.

Ответ 9

Поскольку вы запрашивали самый быстрый:

Если (и только если) структура xml всегда согласована: (это псевдокод)

string xml1 = //get xml1 somehow
string xml2 = //get xml2 somehow
xml1 = replace(xml1, "<?xml version=\"1.0\" encoding=\"utf-8\"?>", "");
xml1 = replace(xml1, "<allnodes>", "");
xml1 = replace(xml1, "</allnodes>", "");
xml2 = replace(xml2, "<allnodes>", "<allnodes>\n" + xml1);

Это гигантский взлом, но он быстро. Ожидайте увидеть его на TheDailyWTF, когда ваши коллеги найдут его.

Ответ 10

var doc = XDocument.Load( "file1.xml" );

var doc1 = XDocument.Load( "file2.xml" );

doc.Root.Add(doc2.Root.Elements());