2017-06-20 48 views
2

私はxmlで始まり​​、C#とlinqの両方で始まります。xmlからデータを取得する(不正な形式ですか?)#

私は、XML

それは同じ要素名と使用が値

の名前をspecififyする属性を使用し作成した

<allegati tot_ele="2"> 
<record> 
<dato nome="IdUnivoco">35516</dato> 
<dato nome="Nome">QUOTAZIONE</dato> 
<dato nome="RelationID">1268</dato> 
<dato nome="nomeFile">1268.pdf</dato> 
</record> 
<record> 
<dato nome="IdUnivoco">35516</dato> 
<dato nome="Nome">CONFERMA D`ORDINE</dato> 
<dato nome="RelationID">1267</dato> 
<dato nome="nomeFile">1267.pdf</dato> 
</record> 
</allegati> 

のこの種は、それぞれの構造体を作成するための簡単な方法がありましたレコードとlinqの構造体のリストを作成すると?私は、文字列の4つの異なるリストを作成するために管理し、現時点で

(私は2ではなく、すべての4ポスト)

List<string> NomeFile1 = (from c in listaAttch.Descendants("dato") 
          where c.Attribute("nome").Value == "nomeFile" 
          select c.Value).ToList(); 

List<string> Relation = (from c in listaAttch.Descendants("dato") 
          where c.Attribute("nome").Value == "RelationID" 
          select c.Value).ToList(); 

その後、私は私のニーズのための4弦

for (int i = 0; i < Relation.Count; i++) 
{ 
    byte[] file = Adiuto.getAttachContent1(login, 35516, Int32.Parse(Relation [i])); 
    System.IO.File.WriteAllBytes("c:\\navision\\" + NomeFile1[i], file); 
. 
. 
. 
} 
を使用するためで

これを行うには、より迅速かつより洗練された方法がありますか? linqを4回繰り返す必要はありませんか? それは、事前にすべての4つの属性値で

感謝を構造体のリストを作成することもOKです

ファブリツィオ

+0

このXMLについては何も変わっていません(または珍しいことでもありません)。 Linqが処理するように設計されたXMLの種類ではありません(簡単に)。 –

答えて

0

あなたは、専用のメソッドにクエリを抽出し、引数として別の値を注入することができます:

private List<string> GetDescendantsValues(SomeType source, string attributeValue) 
{ 
    return source.Descendants("dato") 
     .Where(c => c.Attribute("nome").Value == attributeValue) 
     .Select(c => c.Value).ToList(); 
} 

使用法:

List<string> NomeFile1 = GetDescendantsValues(listaAttch, "nomeFile"); 
List<string> Relation = GetDescendantsValues(listaAttch, "RelationID"); 

もちろん、必要に応じて他の文字列を挿入することもできます。これは、提示されたコードとは異なる唯一のものであるため、1つだけ実行しました。

0

はい、XmlNodeReaderを使用して非標準XML文字列をデシリアライズできます。私のプロジェクトの1つでは、私は同じことをしました。

任意のXML文字列に変換する拡張メソッド - deserialisingのために必要なクラスを生成その後

public static class XmlSerializerExtensions 
{ 
    public static T DeserializeFromNonStandardXmlString<T>(string content) 
    { 
     var xmlDoc = new XmlDocument(); 
     xmlDoc.LoadXml(content); 

     var serializer = typeof(T).IsGenericType ? new XmlSerializer(typeof(T), typeof(T).GenericTypeArguments) : new XmlSerializer(typeof(T)); 
     using (var reader = new XmlNodeReader(xmlDoc)) 
     { 
      return (T)serializer.Deserialize(reader); 
     } 
    } 

    public static object DeserializeFromNonStandardXmlString(Type type, string content) 
    { 
     var xmlDoc = new XmlDocument(); 
     xmlDoc.LoadXml(content); 

     var serializer = type.IsGenericType ? new XmlSerializer(type, type.GenericTypeArguments) : new XmlSerializer(type); 
     using (var reader = new XmlNodeReader(xmlDoc)) 
     { 
      return serializer.Deserialize(reader); 
     } 
    } 
} 

を。そして、あなたはこのようシリアライズすることができます

[XmlRoot(ElementName = "dato")] 
    public class Dato 
    { 
     [XmlAttribute(AttributeName = "nome")] 
     public string Nome { get; set; } 
     [XmlText] 
     public string Text { get; set; } 
    } 

    [XmlRoot(ElementName = "record")] 
    public class Record 
    { 
     [XmlElement(ElementName = "dato")] 
     public List<Dato> Dato { get; set; } 
    } 

    [XmlRoot(ElementName = "allegati")] 
    public class Allegati 
    { 
     [XmlElement(ElementName = "record")] 
     public List<Record> Record { get; set; } 

     [XmlAttribute(AttributeName = "tot_ele")] 
     public string Tot_ele { get; set; } 
    } 

- -

var dt = XmlSerializerExtensions.DeserializeFromNonStandardXmlString<Allegati>(text); 

をそしてなどの項目のリストを取得する - あなたはこのコードを減らすことができ

var NomeFile1 = dt.Record.Select(x => x.Dato.FirstOrDefault(d => d.Nome == "nomeFile")?.Text).Select(x => x != null).ToList(); 
var Relation = dt.Record.Select(x => x.Dato.FirstOrDefault(d => d.Nome == "RelationID")?.Text).Select(x => x != null).ToList(); 

あなたのケースでは、のようなものです同様の方法で -

[XmlRoot(ElementName = "allegati")] 
    public class Allegati 
    { 
     ... 

     public List<string> GetItemsWithKey(string key) 
     { 
      return Record.Select(x => x.Dato.FirstOrDefault(d => d.Nome == key)?.Text).ToList(); 
     } 
    } 



    var dt = XmlSerializerExtensions.DeserializeFromNonStandardXmlString<Allegati>(text); 
    var a = dt.GetItemsWithKey("nomeFile"); 
    var b = dt.GetItemsWithKey("RelationID"); 
関連する問題