Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# xml文档分割算法_C#_Xml_Algorithm - Fatal编程技术网

C# xml文档分割算法

C# xml文档分割算法,c#,xml,algorithm,C#,Xml,Algorithm,我想按指定的节点名将一个xml文档拆分为多个xml文档(类似于string.split(…) 示例:我有以下xml文档 <root> <nodeA> Hello </nodeA> <nodeA> <nodeB> node b Text </nodeB> <nodeImage> i

我想按指定的节点名将一个xml文档拆分为多个xml文档(类似于string.split(…)

示例:我有以下xml文档

<root>
    <nodeA>
        Hello
    </nodeA>
    <nodeA>
        <nodeB>
            node b Text
        </nodeB>
        <nodeImage>
            image.jpg
        </nodeImage>
    </nodeA>
    <nodeA>
        node a text
    </nodeA>
</root>

你好
节点b文本
文件段
为文本添加节点
我想通过“nodeImage”将这个xml文档分成3部分,并保留原始的xml结构。(注意:名为“nodeImage”的节点可以位于任何位置)
1.nodeImage之前的xml
2.用于nodeImage的xml
3.nodeImage之后的xml

对于示例xml,结果应为:

XML文档1:

<root>
    <nodeA>
        Hello
    </nodeA>
    <nodeA>
        <nodeB>
            node b Text
        </nodeB>
    </nodeA>
</root>

你好
节点b文本
XML文档2:

<root>
    <nodeA>
        <nodeImage>
            image.jpg
        </nodeImage>
    </nodeA>
</root>

文件段
XML文档3:

<root>
    <nodeA>
        node a text
    </nodeA>
</root>

为文本添加节点
有人知道这个需求是否有一个好的算法或现有的代码示例吗

更新说明:

如果xml文档中只有一个名为“nodeImage”的节点,则此xml文档应始终拆分为3个xml文档。

类似这样的内容,使用

XElement xe = XElement.Load(XMLFile);

foreach(XElement newXE in xe.Elements("nodeA"))
{
    XElement root = new XElement("root",newXE);
    root.Save(newFile);
}
var doc=XDocument.Parse(stringxml);
var res=新列表();
var cur=新的元素(“根”);
foreach(doc.Element(“root”).Elements(“nodeA”)中的var节点)
{
if(node.Element(“nodeImage”)==null)
{
当前添加(节点);
}
其他的
{
决议添加(当前);
res.Add(新的元素(“根”,节点));
cur=新元素(“根”);
}
}
决议添加(当前);

这很有效。广泛地测试它

var doc = new XmlDocument();
doc.LoadXml(@"<root>
<nodeA>
    Hello
</nodeA>
<nodeA>
    <nodeB>
        node b Text
    </nodeB>
    <nodeImage>
        image.jpg
    </nodeImage>
</nodeA>
<nodeA>
    node a text
</nodeA></root>");

var xmlFrags = new List<string>();
string xml = "<root>";
bool bNewFragment = true;
foreach (XmlNode nodeA in doc.SelectNodes("//root/nodeA")) {
    XmlNode nodeImage = nodeA.SelectSingleNode("nodeImage");
    if (nodeImage != null) {
        xml += "<nodeA>";
        var en = nodeA.GetEnumerator();
        while (en.MoveNext()) {
            XmlNode xn = (XmlNode)en.Current;
            if (xn != nodeImage)
            xml += xn.OuterXml;
        }
        xml += "</nodeA></root>";
        xmlFrags.Add(xml);
        xml = "<root><nodeA>" + nodeImage.OuterXml + "</nodeA></root>";
        xmlFrags.Add(xml);
        bNewFragment = true;
    }
    else 
    {
        if (bNewFragment) {
            xml = "<root>";
            bNewFragment = false;
        }
        xml += nodeA.OuterXml;
    }
}
if (!bNewFragment) {
    xml += "</root>";
    xmlFrags.Add(xml);
}
//Use the XML fragments as you like
foreach (var xmlFrag in xmlFrags)
    Console.WriteLine(xmlFrag + Environment.NewLine);
var doc=new XmlDocument();
doc.LoadXml(@)
你好
节点b文本
文件段
为文本添加节点
");
var xmlFrags=新列表();
字符串xml=”“;
bool bNewFragment=true;
foreach(doc.SelectNodes中的XmlNode nodeA(“//根/nodeA”)){
XmlNode nodeImage=nodeA.SelectSingleNode(“nodeImage”);
if(nodeImage!=null){
xml+=“”;
var en=nodeA.GetEnumerator();
while(en.MoveNext()){
XmlNode xn=(XmlNode)en.Current;
if(xn!=nodeImage)
xml+=xn.OuterXml;
}
xml+=“”;
Add(xml);
xml=”“+nodeImage.OuterXml+”;
Add(xml);
bNewFragment=true;
}
其他的
{
if(bNewFragment){
xml=”“;
bNewFragment=false;
}
xml+=nodeA.OuterXml;
}
}
如果(!bNewFragment){
xml+=“”;
Add(xml);
}
//随意使用XML片段
foreach(xmlFrag中的var xmlFrag)
Console.WriteLine(xmlFrag+Environment.NewLine);
试试这个:

using System;
using System.Xml;

class Program
{
    static void Main(string[] args)
    {
        // create the XML documents
        XmlDocument
            doc1 = new XmlDocument(),
            doc2 = new XmlDocument(),
            doc3 = new XmlDocument();

        // load the initial XMl into doc1
        doc1.Load("input.xml");

        // create the structure of doc2 and doc3
        doc2.AppendChild(doc2.ImportNode(doc1.FirstChild, false));
        doc3.AppendChild(doc3.ImportNode(doc1.FirstChild, false));
        doc2.AppendChild(doc2.ImportNode(doc1.DocumentElement, false));
        doc3.AppendChild(doc3.ImportNode(doc1.DocumentElement, false));

        // select the nodeImage
        var nodeImage = doc1.SelectSingleNode("//nodeImage");
        if (nodeImage != null)
        {
            // append to doc3
            var node3 = nodeImage.ParentNode.NextSibling;
            var n3 = doc3.ImportNode(node3, true);
            doc3.DocumentElement.AppendChild(n3);

            // append to doc2
            var n2 = doc2.ImportNode(nodeImage.ParentNode, true);
            n2.RemoveChild(n2.SelectSingleNode("//nodeImage").PreviousSibling);
            doc2.DocumentElement.AppendChild(n2);

            // remove from doc1
            nodeImage.ParentNode.ParentNode
                .RemoveChild(nodeImage.ParentNode.NextSibling);
            nodeImage.ParentNode
                .RemoveChild(nodeImage);
        }

        Console.WriteLine(doc1.InnerXml);
        Console.WriteLine(doc2.InnerXml);
        Console.WriteLine(doc3.InnerXml);
    }
}
“分割”一词有点令人困惑。一次发作的分裂通常不会产生三个部分

我首先尝试用Linq到xml术语定义您的问题。 对于要创建的XDocument.substands(“nodeImage”)的每次出现:

  • 文档的副本,其中nodeImage父节点已删除nodeImage和所有后续节点。此外,所有祖先必须删除所有下一个节点
  • 文档的副本,其中nodeImage元素的所有祖先都已删除所有XElement.NextNodes和XElement.PreviousNodes
  • 在已删除所有祖先节点的XDocument副本上再次运行此检查
  • 如果没有发现任何事件。正在检查的文档将全部返回
XDocument的深度拷贝很容易。它有一个复制构造函数。 当然,如果您的xml很大,这将占用大量内存

然而,挑战在于在每个副本中定位节点。
显示如何获取元素的XPath。你可以用它。

你能把你的问题看一遍,检查你想要得到的结果是否真的是你键入的文档吗?看起来“XML文档1”中应该只包含第一个“NodeA”…是吗?请参见。请显示您的实现代码。@AlexCube检查我的答案,我认为它可以满足您的需要谢谢,但这不是我想要的。您能更具体一点吗?输出与预期不符。见问题
using System;
using System.Xml;

class Program
{
    static void Main(string[] args)
    {
        // create the XML documents
        XmlDocument
            doc1 = new XmlDocument(),
            doc2 = new XmlDocument(),
            doc3 = new XmlDocument();

        // load the initial XMl into doc1
        doc1.Load("input.xml");

        // create the structure of doc2 and doc3
        doc2.AppendChild(doc2.ImportNode(doc1.FirstChild, false));
        doc3.AppendChild(doc3.ImportNode(doc1.FirstChild, false));
        doc2.AppendChild(doc2.ImportNode(doc1.DocumentElement, false));
        doc3.AppendChild(doc3.ImportNode(doc1.DocumentElement, false));

        // select the nodeImage
        var nodeImage = doc1.SelectSingleNode("//nodeImage");
        if (nodeImage != null)
        {
            // append to doc3
            var node3 = nodeImage.ParentNode.NextSibling;
            var n3 = doc3.ImportNode(node3, true);
            doc3.DocumentElement.AppendChild(n3);

            // append to doc2
            var n2 = doc2.ImportNode(nodeImage.ParentNode, true);
            n2.RemoveChild(n2.SelectSingleNode("//nodeImage").PreviousSibling);
            doc2.DocumentElement.AppendChild(n2);

            // remove from doc1
            nodeImage.ParentNode.ParentNode
                .RemoveChild(nodeImage.ParentNode.NextSibling);
            nodeImage.ParentNode
                .RemoveChild(nodeImage);
        }

        Console.WriteLine(doc1.InnerXml);
        Console.WriteLine(doc2.InnerXml);
        Console.WriteLine(doc3.InnerXml);
    }
}