XPath возвращает ноль в c #, но работает в валидаторе XPath - PullRequest
0 голосов
/ 06 марта 2019

Я впервые использую 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: ProcessType
  • d: Описание
  • и т. д.

но мне не нужны все значения тегов.

Я попробовал онлайновый валидатор Xpath, где я разместил свой XML и использовал это выражение:

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

Это дает мне данныечто мне нужно, но когда я использую его в приложении C # он возвращает ноль.Может кто-нибудь объяснить мне, почему это происходит?И есть ли другой способ сделать это, кроме использования 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();

Ответы [ 3 ]

0 голосов
/ 07 марта 2019

Вы можете создать модель для этого 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.

Счастливого кодирования ...

0 голосов
/ 07 марта 2019

Вот как вы можете вывести отдельные XML-узлы в CSV-файл, используя Cinchoo ETL

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);
0 голосов
/ 07 марта 2019

В онлайн-валидаторе вы используете |, но в своем коде вы используете or. Действительно ли ChoETL меняет способ работы XPath? Я не смог найти доказательств этого в документации.

Кроме того, я думаю, что онлайн-инструмент автоматически определяет префиксы пространства имен, но вы должны сообщить ChoETL пространства имен:

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

и аналогичные.

...