【问题标题】:Avoiding Redundancies in XML documents避免 XML 文档中的冗余
【发布时间】:2011-01-31 06:12:00
【问题描述】:

我正在使用某个没有冗余的 XML

<person>
  <eye>
    <eye_info>
       <eye_color>
       blue
       </eye_color>
    </eye_info>
  </eye>
  <hair>
    <hair_info>
       <hair_color>
       blue
       </hair_color>
    </hair_info>
  </hair>
</person>

如您所见,子标签 eye-color 在其名称中引用了 eye,因此无需避免冗余,在将 XML 加载到数据集后,我可以在一行中获取眼睛颜色:

dataset.ReadXml(path);
value = dataset.Tables("eye_info").Rows(0)("eye_color");

我确实意识到这不是最明智的做法,而且我现在遇到的这种情况并非没有预料到。

现在,假设我必须读取这种格式的 xml:

<person>
  <eye>
    <info>
       <color>
       blue
       </color>
    </info>
  </eye>
  <hair>
    <info>
       <color>
       blue
       </color>
    </info>
  </hair>
</person>

所以如果我尝试这样称呼它:

dataset.ReadXml(path);
value = dataset.Tables("info").Rows(0)("color");

会有冗余,因为我以前的方法只能上一层来识别 XML 中的单个字段,而“消歧器”在上面三层。

在给定上述所有(或至少几个)字段的情况下,是否有一种实用的方法可以准确无误地访问单个字段?

--[编辑]--

我提出了另一个问题,询问如何使用 linq 获取某个节点,check it out

【问题讨论】:

    标签: c# .net xml linq dataset


    【解决方案1】:

    围绕从 XML 文档中查询数据有一个完整的标准。该标准称为 XPath,C# 有一个实现。开箱即用并不是最容易学习的东西,但它是从 XML 中提取数据的最佳技术之一,非常值得学习。

    Here 就是一个例子。

    编辑:我建议您弄清楚 LINQ to XML,但是因为它更强大,但是如果您仍然想要 XPath,那么您的具体问题看起来像(我在这台计算机上没有 VS,所以我无法验证这一点)...

    XPathDocument doc = new XPathDocument(new StringReader(xmlString));
    XPathNavigator nav = doc.CreateNavigator();
    
    // Compile a standard XPath expression
    XPathExpression expr = nav.Compile("/person/eye/eye_info/eye_color");
    expr = nav.Compile("/catalog/cd/price");
    XPathNodeIterator iterator = nav.Select(expr);
    
    // Iterate on the node set
    while (iterator.MoveNext())
    {
       XPathNavigator nav2 = iterator.Current.Clone();
       Console.WriteLine(nav2.Value);
    }
    

    【讨论】:

    • 我会试试 xpath 的!你能给我举个例子吗?检查问题中的更新
    • 有关 XPath 的一般介绍,请查看 w3schools.com/xpath/default.asp。在 .Net 中,XPath 可通过 XmlNode 对象及其后代(即 XmlDocument)上的 SelectNode 和 SelectNodes 方法获得。
    【解决方案2】:

    您还可以使用 Linq to XML(System.Xml.Linq 命名空间)并像这样检索您的数据

    string xml = @"<persons>
    <person> 
      <eye> 
        <info> 
           <color>blue</color> 
        </info> 
      </eye> 
      <hair> 
        <info> 
           <color>blonde</color> 
        </info> 
      </hair> 
    </person>
    <person> 
      <eye> 
        <info> 
           <color>green</color> 
        </info> 
      </eye> 
      <hair> 
        <info> 
           <color>brown</color> 
        </info> 
      </hair> 
    </person>
    </persons>";
    
    XDocument document = XDocument.Parse(xml);
    
    var query = from person in document.Descendants("person")
                select new
                {
                    EyeColor = person.Element("eye").Element("info").Element("color").Value,
                    HairColor = person.Element("hair").Element("info").Element("color").Value
                };
    
    foreach (var person in query)
        Console.WriteLine("{0}\t{1}", person.EyeColor, person.HairColor);
    

    【讨论】:

    • 我会使用 Linq to Xml to,这很自然。
    • 谢谢,我在尝试使用时遇到了问题..检查更新
    【解决方案3】:

    记住DataSet类只能理解可以翻译成关系数据库形式的XML。特别是,它不会处理具有多个父“表”的单个子“表”。将“信息”元素作为人、头发和眼睛的子元素就是一个例子。

    【讨论】:

      猜你喜欢
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 2019-01-02
      • 1970-01-01
      • 2017-08-10
      • 1970-01-01
      • 1970-01-01
      • 2015-08-12
      相关资源
      最近更新 更多