C#返回一个包含祖先和self的XML元素,但不返回其他子元素
我有这样一个xml文档布局C#返回一个包含祖先和self的XML元素,但不返回其他子元素,c#,xml,linq,linq-to-xml,C#,Xml,Linq,Linq To Xml,我有这样一个xml文档布局 <?xml version="1.0" encoding="utf-8" ?> <Document name="document name"> <DataSet name="dataset 1"> <Dimension name="dimension 1"> <Metric name="metric 1"> <Data va
<?xml version="1.0" encoding="utf-8" ?>
<Document name="document name">
<DataSet name="dataset 1">
<Dimension name="dimension 1">
<Metric name="metric 1">
<Data value="1">
<Data value="2">
<Data value="3">
</Metric>
<Metric name="metric 2">
<Data value="4">
<Data value="5">
<Data value="6">
</Metric>
</Dimension>
<Dimension name="dimension 2">
<Metric name="metric 3">
<Data value="6">
<Data value="7">
<Data value="8">
</Metric>
<Metric name="metric 4">
<Data value="9">
<Data value="10">
<Data value="11">
</Metric>
</Dimension>
</DataSet>
</Document>
还要注意的是,如果我使用下面的代码,我会得到我要寻找的确切指标,但我需要将它们封装在它们的父级中
IEnumerable<XElement> elementsInPath = doc.Descendants(elementName)
.Where(p => p.Attribute(attributeName).Value.Contains(attributeValue))
.InDocumentOrder()
.ToList();
IEnumerable elementsInPath=doc.substands(elementName)
.Where(p=>p.attributeName.Value.Contains(attributeValue))
.InDocumentOrder()
.ToList();
因此,您实际上是在为每个指标
元素构建一个新文档。最直接的方法是:
foreach (XElement el in doc.Root.Descendants("Metric"))
{
XElement newDoc =
new XElement("Document",
new XAttribute(doc.Root.Attribute("name")),
new XElement("DataSet",
new XAttribute(el.Parent.Parent.Attribute("name")),
new XElement("Dimension",
new XAttribute(el.Parent.Attribute("name")),
el)
)
)
);
newDoc.Save(el.Attribute("name").Value.Replace(" ", "_") + ".xml");
}
这很有希望地说明了动态版本的工作原理——遍历祖先并基于它们创建新元素:
foreach (XElement el in doc.Root.Descendants("Metric"))
{
XElement newDoc = el;
foreach(XElement nextParent in el.Ancestors()) // iterate through ancestors
{
//rewrap in ancestor node name/attributes
newDoc = new XElement(nextParent.Name, nextParent.Attributes(), newDoc);
}
newDoc.Save(el.Attribute("name").Value.Replace(" ", "_") + ".xml");
}
仅仅使用
祖先()
功能是行不通的,因为当您尝试添加它们时,它也会添加它们的子元素(您尝试拆分的元素的兄弟姐妹)。我正要问,如果没有.anteStorsandself()
部分,您会得到什么,但您是有远见的:)是的,我的节点名称将是动态的。我有一个表单,它将采用elementName来搜索/拆分文档。因此,我需要一种方法以编程方式获取元素“metric”的所有父元素。我想我可以检索元素,然后在递归循环中不断请求其父元素,但我不知道如何重新构建文件。谢谢!这很有魅力。现在,我看到您使用原始文档中的名称和属性构建了一个新的父元素,这样就没有子元素了。对-这基本上就是我在“静态”版本中所做的,但是现在我已经设置了从父元素获取所有属性和名称。
int i = 1;
foreach (XElement element in elementsInPath)
{
XDocument tmpDoc = new XDocument();
tmpDoc.Add(element);
tmpDoc.Save(outputDirectory + elementName + "_" + i + ".xml");
i++;
}
IEnumerable<XElement> elementsInPath = doc.Descendants(elementName)
.Where(p => p.Attribute(attributeName).Value.Contains(attributeValue))
.InDocumentOrder()
.ToList();
foreach (XElement el in doc.Root.Descendants("Metric"))
{
XElement newDoc =
new XElement("Document",
new XAttribute(doc.Root.Attribute("name")),
new XElement("DataSet",
new XAttribute(el.Parent.Parent.Attribute("name")),
new XElement("Dimension",
new XAttribute(el.Parent.Attribute("name")),
el)
)
)
);
newDoc.Save(el.Attribute("name").Value.Replace(" ", "_") + ".xml");
}
foreach (XElement el in doc.Root.Descendants("Metric"))
{
XElement newDoc = el;
foreach(XElement nextParent in el.Ancestors()) // iterate through ancestors
{
//rewrap in ancestor node name/attributes
newDoc = new XElement(nextParent.Name, nextParent.Attributes(), newDoc);
}
newDoc.Save(el.Attribute("name").Value.Replace(" ", "_") + ".xml");
}