2016-10-28 1 views
0

C# Linq XDocument를 사용하여 작은 XML 파일을 작성하려고합니다.C# Linq XDoc - 같은 이름의 요소를 추가하십시오.

최종 XML 파일은 다음과 같이한다 : 나는 두 번째 "FIELD"요소에 넣어하려고 할 때까지

XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", null)); 
doc.Add(new XElement("Root")); 
doc.Element("Root").Add(new XElement("Asset")); 
doc.Element("Root").Element("Asset").Add(new XAttribute("InternalID", a.InternalID)); 
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveDate", a.lastSaveDate)); 
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveTime", a.lastSaveTime)); 
doc.Element("Root").Element("Asset").Add(new XAttribute("AssetType", a.AssetType)); 
doc.Element("Root").Element("Asset").Add(new XElement("type_metadata")); 

doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD")); 
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Add(new XAttribute("name","filename")); 
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Value = a.filename; 

doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD")); 
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Add(new XAttribute("name", "duration")); 
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Value = a.duration; 

모든 것이 잘 작동 :

<?xml version="1.0" encoding="utf-8"?> 
<Root> 
    <Asset InternalID="SOMEID" LastSaveDate="2016-10-28" LastSaveTime="01:01:33:00" AssetType="New"> 
    <type_metadata> 
     <FIELD name="filename">SOMEID.MOV</FIELD> 
     <FIELD name="duration">00:00:00:10</FIELD> 
    </type_metadata> 
    </Asset> 
</Root> 

여기 내 코드입니다. 이 작업을 수행하는 올바른 방법은 무엇입니까? 나는 약간의 연구를 해왔지만, 내가 성취하고자하는 것에 직접적으로 관련된 간단한 대답을 찾을 수 없다.

+0

마지막 세 줄에는 두 번째 요소 인 "FIELD"(속성이 다름)가 추가됩니다. 이 오류는 System.Xml.Linq.dll에서 'System.InvalidOperationException'형식의 처리되지 않은 예외가 발생했습니다. 메시지 : 중복 특성입니다. –

답변

1

당신이 두 번째 요소를 추가하려고 할 때 당신이 사용하고 있기 때문에 그 :

doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD") 

이름에 일치하는 첫 번째 요소를 반환합니다.이 경우 이미 "name"특성을 가진이 추가 된 "FIELD"요소가 추가 된 입니다.

문서에 첨부하기 전에 요소 자체를 만드는 것이 좋습니다. 당신은 필요가 없습니다 이런 식으로 반복해서 요소를 검색하려면 :

XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", null)); 

var root = new XElement("Root"); 

var asset = new XElement("Asset"); 
asset.Add(new XAttribute("InternalID", a.InternalID)); 
asset.Add(new XAttribute("LastSaveDate", a.lastSaveDate)); 
asset.Add(new XAttribute("LastSaveTime", a.lastSaveTime)); 
asset.Add(new XAttribute("AssetType", a.AssetType)); 

var type_metadata = new XElement("type_metadata"); 

var field = new XElement("FIELD"); 
field.Add(new XAttribute("name","filename")); 
field.Value = a.filename; 

type_metadata.Add(field); 

var field2 = new XElement("FIELD"); 
field2.Add(new XAttribute("name","duration")); 
field2.Value = a.duration; 

type_metadata.Add(field2); 

asset.Add(type_metadata); 

root.Add(asset); 

doc.Add(root); 

을 또한, 단일 문에서 전체 문서를 만들 수 있습니다

XDocument doc = new XDocument(
    new XDeclaration("1.0", "UTF-8", null), 
    new XElement("Root", 
     new XElement("Asset", 
      new XAttribute("InternalID", a.InternalID), 
      new XAttribute("LastSaveDate", a.lastSaveDate), 
      new XAttribute("LastSaveTime", a.lastSaveTime), 
      new XAttribute("AssetType", a.AssetType), 
      new Element("type_metadata", 
       new XElement("FIELD", 
        new XAttribute("name", "filename"), 
        a.filename), 
       new XElement("FIELD", 
        new XAttribute("name", "duration"), 
        a.duration))))); 
+0

감사합니다. 단일 성명은 완벽하게 작동했습니다. 나는 지금부터 그 방법을 사용할 것이다. 이렇게하면 XML을 많이 사용하면서 시간을 많이 절약 할 수 있습니다. –

1

상위 요소에 추가하기 전에 새로운 FIELD 요소를 준비하는 경우가 쉬울 것이다 :

var filename = new XElement("FIELD", 
        new XAttribute("name","filename"), 
        a.filename 
       ); 
var duration = new XElement("FIELD", 
        new XAttribute("name","duration"), 
        a.duration 
       ); 
doc.Element("Root").Element("Asset").Element("type_metadata").Add(field); 
doc.Element("Root").Element("Asset").Element("type_metadata").Add(duration); 
0

이 서로 다른 달성 할 수있다 방법. 방금 당신의 접근 방식을 따랐습니다. 여러 FIELD 요소가 있으므로 코드에서 약간의 수정이 필요합니다. 다음 코드는 예상대로 작동합니다.

XDocument doc = new XDocument(new XDeclaration("1.0", "UTF-8", null)); 
doc.Add(new XElement("Root")); 
doc.Element("Root").Add(new XElement("Asset")); 
doc.Element("Root").Element("Asset").Add(new XAttribute("InternalID", "intID")); 
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveDate", "28.10.2016")); 
doc.Element("Root").Element("Asset").Add(new XAttribute("LastSaveTime", "1.48PM")); 
doc.Element("Root").Element("Asset").Add(new XAttribute("AssetType", "Laptop")); 
doc.Element("Root").Element("Asset").Add(new XElement("type_metadata")); 

doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD")); 
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Add(new XAttribute("name", "filename")); 
doc.Element("Root").Element("Asset").Element("type_metadata").Element("FIELD").Value = "a.txr"; 

doc.Element("Root").Element("Asset").Element("type_metadata").Add(new XElement("FIELD")); 
doc.Element("Root").Element("Asset").Element("type_metadata").Elements().Last().Add(new XAttribute("name", "duration")); 
doc.Element("Root").Element("Asset").Element("type_metadata").Elements().Last().Value = "00:12:98";