【问题标题】:XPath returns null in c# but works in XPath validatorXPath 在 c# 中返回 null 但在 XPath 验证器中有效
【发布时间】:2019-03-06 20:36:33
【问题描述】:

这是我第一次使用 XPath。

这是我的 XML:

<content type="application/xml">
    <m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
        <d:Guid>YOIYOI-HNON-OIN</d:Guid>
        <d:ObjectId>6000009251</d:ObjectId>
        <d:ProcessType>ZMIN</d:ProcessType>
        <d:ProcessTypeTxt>Incident</d:ProcessTypeTxt>
        <d:Description>Test 2</d:Description>
        <d:IntroText>Incident</d:IntroText>
        <d:CreatedAtDateFormatted>08.05.18</d:CreatedAtDateFormatted>
        <d:ChangedAtDateFormatted>08.05.18</d:ChangedAtDateFormatted>
        <d:PostingDate>2018-05-08T00:00:00</d:PostingDate>
        <d:ChangedAtDate>2018-05-08T00:00:00</d:ChangedAtDate>
        <d:Priority>2</d:Priority>
        <d:PriorityTxt>2: High</d:PriorityTxt>
        <d:PriorityState>None</d:PriorityState>
        <d:Concatstatuser>New</d:Concatstatuser>
        <d:ActionRequired>false</d:ActionRequired>
        <d:StillOpen>true</d:StillOpen>
        <d:Icon></d:Icon>
        <d:SoldToPartyName></d:SoldToPartyName>
        <d:ServiceTeamName></d:ServiceTeamName>
        <d:PersonRespName></d:PersonRespName>
        <d:ConfigItemTxt></d:ConfigItemTxt>
    </m:properties>
</content>

还有其他内容节点。

我需要检索特定的标签值,例如:

  • d:Guid
  • d:进程类型
  • d:描述
  • 等等..

但我不需要所有标签值。

我尝试了一个在线 Xpath 验证器,我在其中发布了我的 XML 并使用了这个表达式:

//content/m:properties/d:Guid | //content/m:properties/d:ObjectId

这为我提供了我需要的数据,但是当我在 c# 应用程序中使用它时,它返回 null。有人可以向我解释为什么会这样吗?除了使用 XPath 之外,还有其他方法吗?

这是我的 C# 代码:

string xml = System.IO.File.ReadAllText(startupPath);
StringBuilder sb = new StringBuilder();

using (var node = ChoXmlReader.LoadText(xml).WithXPath("//content/m:properties/d:Guid or //content/m:properties/d:ObjectId"))
{
    using (var w = new ChoCSVWriter(sb).WithFirstLineHeader())
    {
        w.Write(node);
    }
}

Console.WriteLine(sb.ToString());
Console.ReadLine();

【问题讨论】:

  • 欢迎来到 Stack Overflow。请您提供minimal reproducible example 吗?我们不知道ChoXmlReaderChoCSVWriter 是什么——后者听起来与问题无关。 (但不,您不需要使用 XPath 来查询 XML。我个人只是直接使用 LINQ to XML。)
  • 根据您的 cmets,听起来您想从 XML(d:Guid、d:ProcessType 等)中检索多个节点并将它们写入 CSV。你现在的代码不起作用,你必须使用ChoETL吗?如果不是@JonSkeet 是正确的,那么你最好使用 LINQ to XML,它有很多在线示例。

标签: c# validation xpath choetl


【解决方案1】:

在在线验证器中,您使用|,但您在代码中使用or。 ChoETL 真的改变了 XPath 的工作方式吗?我在文档中找不到这方面的证据。

另外,我认为在线工具会自动推断命名空间前缀,但您需要告诉 ChoETL 命名空间:

.WithXNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices")

和类似的。

【讨论】:

  • AFAIK,| 应该合并结果集,而or 返回一个布尔表达式,如果有节点,则导致true。如果 ChoETL 改变了这种行为,那将是相当令人惊讶的。
  • using (var node = ChoXmlReader.LoadText(xml) .WithXPath("//content/m:properties/d:Guid | //content/m:properties/d:ObjectId") .WithXmlNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata") .WithXmlNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices")) { using (var w = new ChoCSVWriter(sb).WithFirstLineHeader()) { w.Write(node); } } 这仍然不起作用:s
  • @lifeTech:“不起作用”不是一个很有帮助的说法。错误信息或结果是什么?
  • 没有错误它甚至没有在控制台上输出字符串。
  • 你肯定需要学习如何使用调试器。对不起。我帮不上忙。
【解决方案2】:

您可以为此 XML 文件创建一个模型,然后将其序列化为对象,然后访问所需的属性。这是您可以使用的模型:

[XmlRoot(ElementName = "properties", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")]
    public class Properties
    {
        [XmlElement(ElementName = "Guid", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string Guid { get; set; }
        [XmlElement(ElementName = "ObjectId", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string ObjectId { get; set; }
        [XmlElement(ElementName = "ProcessType", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string ProcessType { get; set; }
        [XmlElement(ElementName = "ProcessTypeTxt", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string ProcessTypeTxt { get; set; }
        [XmlElement(ElementName = "Description", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string Description { get; set; }
        [XmlElement(ElementName = "IntroText", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string IntroText { get; set; }
        [XmlElement(ElementName = "CreatedAtDateFormatted", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string CreatedAtDateFormatted { get; set; }
        [XmlElement(ElementName = "ChangedAtDateFormatted", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string ChangedAtDateFormatted { get; set; }
        [XmlElement(ElementName = "PostingDate", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string PostingDate { get; set; }
        [XmlElement(ElementName = "ChangedAtDate", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string ChangedAtDate { get; set; }
        [XmlElement(ElementName = "Priority", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string Priority { get; set; }
        [XmlElement(ElementName = "PriorityTxt", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string PriorityTxt { get; set; }
        [XmlElement(ElementName = "PriorityState", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string PriorityState { get; set; }
        [XmlElement(ElementName = "Concatstatuser", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string Concatstatuser { get; set; }
        [XmlElement(ElementName = "ActionRequired", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string ActionRequired { get; set; }
        [XmlElement(ElementName = "StillOpen", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string StillOpen { get; set; }
        [XmlElement(ElementName = "Icon", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string Icon { get; set; }
        [XmlElement(ElementName = "SoldToPartyName", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string SoldToPartyName { get; set; }
        [XmlElement(ElementName = "ServiceTeamName", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string ServiceTeamName { get; set; }
        [XmlElement(ElementName = "PersonRespName", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string PersonRespName { get; set; }
        [XmlElement(ElementName = "ConfigItemTxt", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices")]
        public string ConfigItemTxt { get; set; }
        [XmlAttribute(AttributeName = "m", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string M { get; set; }
        [XmlAttribute(AttributeName = "d", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string D { get; set; }
    }

    [XmlRoot(ElementName = "content")]
    public class Content
    {
        [XmlElement(ElementName = "properties", Namespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata")]
        public Properties Properties { get; set; }
        [XmlAttribute(AttributeName = "type")]
        public string Type { get; set; }
    }

这里是将其转换为对象的C# 代码:

XmlSerializer serializer = new XmlSerializer(typeof(Content));
 Content resultingMessage = (Content)serializer.Deserialize(new XmlTextReader(@"XMLFile1.xml"));

这是访问 guid 属性的代码:

string guid = resultingMessage.Properties.Guid;

希望这能解决您的问题。

PS:我已经根据你给定的XML文件创建了模型,如果这个XML schema发生变化,你需要相应地修改你的model

编码愉快...

【讨论】:

    【解决方案3】:

    这是使用 Cinchoo ETL 将选择性 xml 节点输出到 csv 文件的方法

    var nsManager = new XmlNamespaceManager(new NameTable());
    //register mapping of prefix to namespace uri 
    nsManager.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
    nsManager.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
    
    StringBuilder csv = new StringBuilder();
    using (var p = ChoXmlReader.LoadText(xml)
            .WithXPath("//entry/content/m:properties")
            .WithXmlNamespaceManager(nsManager)
            .WithField("Guid", xPath: "d:Guid")
            .WithField("ProcessType", xPath: "d:ProcessType")
            .WithField("Description", xPath: "d:Description")
        )
    {
        using (var w = new ChoCSVWriter(csv)
            .WithFirstLineHeader()
            )
            w.Write(p);
    }
    
    Console.WriteLine(csv);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-11
      • 2019-01-07
      • 2016-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      相关资源
      最近更新 更多