C# 带有LINQ的XElement在特定节点后添加节点
我得到了这个XML:C# 带有LINQ的XElement在特定节点后添加节点,c#,xml,linq,xelement,C#,Xml,Linq,Xelement,我得到了这个XML: <?xml version="1.0" encoding="utf-8"?> <JMF SenderID="InkZone-Controller" Version="1.2"> <Command ID="cmd.00695" Type="Resource"> <ResourceCmdParams ResourceName="InkZoneProfile" JobID="K_41"> <InkZon
<?xml version="1.0" encoding="utf-8"?>
<JMF SenderID="InkZone-Controller" Version="1.2">
<Command ID="cmd.00695" Type="Resource">
<ResourceCmdParams ResourceName="InkZoneProfile" JobID="K_41">
<InkZoneProfile ID="r0013" Class="Parameter" Locked="false" Status="Available" PartIDKeys="SignatureName SheetName Side Separation" DescriptiveName="Schieberwerte von DI" ZoneWidth="32">
<InkZoneProfile SignatureName="SIG1">
<InkZoneProfile Locked="False" SheetName="S1">
<InkZoneProfile Side="Front">
<ColorPool Class="Parameter" DescriptiveName="Colors for the job" Status="Available">
<InkZoneProfile Separation="PANTONE 647 C" ZoneSettingsX="0 0,003 " />
</ColorPool>
</InkZoneProfile>
</InkZoneProfile>
</InkZoneProfile>
</InkZoneProfile>
</ResourceCmdParams>
</Command>
</JMF>
这是:
XmlDoc.Element("JMF")
.Elements("InkZoneProfile").Where(InkZoneProfile => InkZoneProfile.Attribute("Side")
.Value == "Front").FirstOrDefault().AddAfterSelf(new XElement("InkZoneProfile",
new XAttribute("Separation", x.colorname),
new XAttribute("ZoneSettingsX", x.colorvalues)));
我根据以下示例构建了此查询:
但它并没有像预期的那样起作用。LINQ查询有什么问题?从我所读的内容来看,它应该是有效的(从逻辑上阅读表达式,我可以理解它)
谢谢
EDIT-1:整个writexml方法
public void writexml(xmldatalist,变量GlobalVars)
{
XmlWriterSettings设置=新的XmlWriterSettings
{
缩进=真,
IndentChars=“\t”,
NewLineChars=Environment.NewLine,
NewLineHandling=NewLineHandling.Replace,
编码=新的UTF8编码(错误)
};
字符串DesktopFolder=Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
字符串FileExtension=“.xml”;
string PathString=Path.Combine(DesktopFolder,“XML”);
System.IO.Directory.CreateDirectory(路径字符串);
foreach(XMLList.XMLArrayList中的列表i)
{
int m=0;
foreach(i中的变量x)
{
字符串XMLFilename=System.IO.Path.GetFileNameWithoutExtension(x.xml\u文件名);
GlobalVars.FullPath=Path.Combine(路径字符串,XMLFilename+FileExtension);
如果(!File.Exists(GlobalVars.FullPath))
{
XDocument doc=新XDocument(
新的XDE声明(“1.0”、“utf-8”、“是”),
新XElement(“JMF”,
新XAttribute(“SenderID”、“InkZone控制器”),
新XAttribute(“版本”、“1.2”),
新XElement(“命令”,
新的XAttribute(“ID”,“cmd.00695”),
新XAttribute(“类型”、“资源”),
新XElement(“ResourceCmdParams”,
新XAttribute(“ResourceName”、“InkZoneProfile”),
新的XAttribute(“JobID”、“K_41”),
新XElement(“InkZoneProfile”,
新的X属性(“ID”、“r0013”),
新XAttribute(“类”、“参数”),
新XAttribute(“锁定”、“错误”),
新XAttribute(“状态”、“可用”),
新XAttribute(“PartIDKeys”、“SignatureName SheetName侧分隔”),
新XAttribute(“描述名称”、“Schieberwette von DI”),
新的X属性(“区域宽度”、“32”),
新XElement(“InkZoneProfile”,
新XAttribute(“SignatureName”、“SIG1”),
新XElement(“InkZoneProfile”,
新XAttribute(“锁定”、“错误”),
新XAttribute(“SheetName”、“S1”),
新XElement(“InkZoneProfile”,
新XAttribute(“侧面”、“正面”),
新的XElement(“ColorPoolClass”,
新XAttribute(“类”、“参数”),
新XAttribute(“描述名称”、“工作颜色”),
新特性(“状态”、“可用”)
)))))))));
保存文件(全局文件路径);
XDocument XmlDoc=新XDocument();
XmlDoc=XDocument.Load(GlobalVars.FullPath);
XElement InkZonePath=XmlDoc.Root.substands(“InkZoneProfile”)。其中(z=>(string)z.Attribute(“Side”)==“Front”).SingleOrDefault();
如果(InkZonePath!=null)
{
InkZonePath.AddAfterSelf(新的XElement(“InkZoneProfile”),
新XAttribute(“分离”,x.colorname),
新的XAttribute(“ZoneSettingsX”,x.colorvalues));
}
Save(GlobalVars.FullPath);
}//正在关闭!文件已存在
}//闭合内孔
}//闭合外foreach
}//关闭writexml方法
您需要使用子体
方法来代替元素
:
XElement InkZonePath = XmlDoc.Root.Descendants("InkZoneProfile").Where(z => (string)z.Attribute("Side") == "Front").SingleOrDefault();
if(InkZonePath !=null)
InkZonePath.AddAfterSelf(new XElement("InkZoneProfile",
new XAttribute("Separation", x.colorname),
new XAttribute("ZoneSettingsX", x.colorvalues)));
您可以改为使用子体
var node = XmlDoc.Descendants("InkZoneProfile").Where(x=> x.Attribute("Side") !=null && x.Attribute("Side").Value == "Front").FirstorDefault();
当前代码的问题在于:
Element(“JMF”).Elements(“InkZoneProfile”)
因为InkZoneProfile
不是JMF
的直接子级,所以它不会返回任何内容。改用子体
这将为您提供正确的结果:-
XElement InkZonePath = xdoc.Element("JMF").Descendants("InkZoneProfile")
.SingleOrDefault(z => (string)z.Attribute("Side") == "Front")
在此之后,您可以使用AddAfterSelf
添加任何要添加的节点。请注意,我在这里使用了SunLeRealDebug,但是如果您有多个匹配节点,则可能会遇到异常,在这种情况下,请考虑使用FrestRealSuff.
更新:
要添加新节点,请执行以下操作:-
if (InkZonePath != null)
{
InkZonePath.AddAfterSelf(new XElement("InkZoneProfile",
new XAttribute("Separation", "Test"),
new XAttribute("ZoneSettingsX", "Test2")));
}
//Save XDocument
xdoc.Save(@"C:\Foo.xml");
我认为您想要的是
子体
而不是元素
。看到了吗,这抛出了一个异常。对象实例未设置为对象的实例。@PabloCosta Linq查询正确。……您的XmlDoc是什么类型的?你能再检查一下吗?@PabloCosta是的,找到了…HasAttrbutes属性使用不正确…尝试新代码它工作了!谢谢但是现在如何添加此节点?如果我把这个放在那里,数据就不会被添加。我不能使用xmlDoc.Add(node)。@PabloCosta Xelement是引用类型,所以您对该Xelement所做的任何更改都会反映在xmlDoc中,以使其正常工作。谢谢现在,我只是在将这个新元素添加到xdoc@PabloCosta-有什么问题?只需检查InkZonePath
是否不为空。然后说:InkZonePath.AddAfterSelf(新的XElement(“InkZoneProfile”),然后保存Xml
XElement InkZonePath = xdoc.Element("JMF").Descendants("InkZoneProfile")
.SingleOrDefault(z => (string)z.Attribute("Side") == "Front")
if (InkZonePath != null)
{
InkZonePath.AddAfterSelf(new XElement("InkZoneProfile",
new XAttribute("Separation", "Test"),
new XAttribute("ZoneSettingsX", "Test2")));
}
//Save XDocument
xdoc.Save(@"C:\Foo.xml");