我有这个XML的问题,我想提取ea_source名称

时间:2012-10-24 16:01:08

标签: c# xml linq linq-to-xml

ea_sourceName的值为ea_targetName时,我想提取ea_typeAggregation的值。

 <UML:Association xmi.id="EAID_018EEEB3_9A6B_4102_85C8_3A78261E9AA4" visibility="public" isRoot="false" isLeaf="false" isAbstract="false">
 <UML:ModelElement.taggedValue>
  <UML:TaggedValue tag="style" value="3" /> 
  <UML:TaggedValue tag="ea_type" value="Aggregation" /> 
  <UML:TaggedValue tag="direction" value="Source -> Destination" /> 
  <UML:TaggedValue tag="linemode" value="3" /> 
  <UML:TaggedValue tag="linecolor" value="-1" /> 
  <UML:TaggedValue tag="linewidth" value="0" /> 
  <UML:TaggedValue tag="seqno" value="0" /> 
  <UML:TaggedValue tag="headStyle" value="0" /> 
  <UML:TaggedValue tag="lineStyle" value="0" /> 
  <UML:TaggedValue tag="ea_localid" value="8" /> 
  <UML:TaggedValue tag="ea_sourceName" value="Course" /> 
  <UML:TaggedValue tag="ea_targetName" value="Sem_Progarm" /> 
  <UML:TaggedValue tag="ea_sourceType" value="Class" /> 
  <UML:TaggedValue tag="ea_targetType" value="Class" /> 
  <UML:TaggedValue tag="ea_sourceID" value="18" /> 
  <UML:TaggedValue tag="ea_targetID" value="19" /> 
  <UML:TaggedValue tag="virtualInheritance" value="0" /> 
  </UML:ModelElement.taggedValue>

我试过这段代码,但它没有返回任何内容。我想要的是一个包含ea_sourceName的值的列表,如Course等等

static XNamespace ns2;
ns2 = @"omg.org/UML1.3";
XDoucument MyXmiFile = XDocument.Load(path);
 string Relation = "Association";
 var q = from p in this.MyXmiFile.Descendants(ns2 + Relation)
         select p;

 var m = from p in q.Descendants(ns2 + "TaggedValue")
         where p.Attribute("tag").Value == "ea_type" && p.Attribute("value").Value == "Aggregation"
         select p;

var s = from p in m
        let P1 = p.Attribute("tag").Value
        where P1 == "ea_sourceName"
        select p.Attribute("value").Value;

List<string> Result = new List<string>(s.ToList());

2 个答案:

答案 0 :(得分:0)

使用this xml library,我使用XPath获取tag = ea_type及其value = Aggregation的所有TaggedValue。然后我为每个元素创建一个<tag, value>字典。

XElement root = XElement.Load(file); // or .Parse(xmlstring)
var agg = root.XPath("//TaggedValue[@tag='ea_type' and @value={0}]", "Aggregation");
List<Dictionary<string,string>> list = agg.Select(a => a.Parent.Elements()
        .ToDictionary(b => b.Attribute("tag").Value, 
                      b => b.Attribute("value").Value))
        .ToList();

我将"Aggregation"参数设置为XPath方法,它可能是硬编码的,但我认为它可能是可变的。这取决于你。

答案 1 :(得分:0)

假设可以有多个具有该类型的关联,这里有一个可以为您获取它们的查询:

var doc = XDocument.Load(path);
var relation = "Association";
var targetType = "Aggregation";
XNamespace UML = "omg.org/UML1.3";
var associations =
    from association in doc.Descendants(UML + relation)
    let values = association.Element(UML + "ModelElement.taggedValue")
    where ReadTaggedValue(values, "ea_type") == targetType
    select new
    {
        ea_sourceName = ReadTaggedValue(values, "ea_sourceName"),
        ea_targetName = ReadTaggedValue(values, "ea_targetName"),
    };

用一个小帮助方法来读取标记值:

string ReadTaggedValue(XElement values, string tag)
{
    XNamespace UML = "omg.org/UML1.3";
    return values.Elements(UML + "TaggedValue")
        .Where(e => (string)e.Attribute("tag") == tag)
        .Select(e => (string)e.Attribute("value"))
        .Single();
}