2016-04-28 3 views
0

Я пытаюсь упростить следующий код. Он отлично работает, но я хотел бы реорганизовать его с помощью LINQ.C# LINQ возвращающее значение из родительского узла в xml

я только был в состоянии работать его с помощью 2 отдельных запросов к и два отдельных массива:

var testid = xliff.Descendants() 
        .Elements(xmlns + "trans-unit") 
        .Elements(xmlns + "seg-source") 
        .Elements(xmlns + "mrk") 
        .Where(e => e.Attribute("mtype").Value == "seg").ToArray(); 

string[] parentids = new string[testid.Length]; 
int counter = 0; 
foreach (var item in testid) 
{ 
    XElement testelement = item.Parent.Parent.PreviousNode as XElement; 
    parentids[counter] = testelement.Elements(xmlns + "source") 
            .Elements(xmlns + "x") 
            .LastOrDefault() 
            .Attribute("id") 
            .Value.ToString(); 
    counter++; 
} 

Обновленный код:

var parentids = xliff.Descendants() 
        .Elements(xmlns + "trans-unit") 
        .Elements(xmlns + "seg-source") 
        .Elements(xmlns + "mrk") 
        .Where(e => e.Attribute("mtype").Value == "seg") 
        .Select(item => (XElement)item.Parent.Parent.PreviousNode) 
        .Where(item => item != null) 
        .Select(item => item.Elements(xmlns + "source") 
        .Where(itema => itema != null) 
        .Select(itemb => itemb.Elements(xmlns + "x")    
        .LastOrDefault() 
        .Attribute("id") 
        .Value.ToString())).ToArray(); 

Я хотел бы видеть, если это может быть решена с помощью один запрос LINQ. Благодарю.

Update: Образец часть XLIFF я пытаюсь разобрать:

Вот фрагмент из XML, так что вы видите, что я пытаюсь получить:

<?xml version="1.0" encoding="utf-8"?> 
<xliff xmlns:sdl="http://sdl.com/FileTypes/SdlXliff/1.0" version="1.2" sdl:version="1.0" xmlns="urn:oasis:names:tc:xliff:document:1.2"> 
<!-- xliff goes on here --> 
    <trans-unit id="495bbe35-ad63-4d37-91e0-8261c2e4052e" translate="no"> 
    <source> 
     <x id="11" /> 
     <x id="12" />  <!-- THIS IS THE ID I WANT TO GET PARSED --> 
    </source> 
    </trans-unit> 
    <trans-unit id="5bccf5f4-56c9-4969-8416-f3114eb36e86"> 
    <source> 
     <x id="13" />SOME TEXT 
    </source> 
    <seg-source> 
     <mrk mtype="seg" mid="6">  <!-- THIS IS THE 'MID' I WANT TO START FROM --> 
     <x id="13" />SOME TEXT 
     </mrk> 
    </seg-source> 
    <target> 
     <mrk mtype="seg" mid="6"> 
     <x id="13" />SOME TRANSLATION 
     </mrk> 
    </target> 
    <sdl:seg-defs> 
     <sdl:seg id="6" conf="ApprovedTranslation" origin="interactive" /> 
    </sdl:seg-defs> 
    </trans-unit> 

Update :

XMLtype2:

<?xml version="1.0" encoding="utf-8"?><xliff xmlns:sdl="http://sdl.com/FileTypes/SdlXliff/1.0" xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2" sdl:version="1.0"><file original="C:\Users\talentbi\AppData\Local\Temp\88f49a09-41ef-4777-ab1e-931fed467885\4D_Kit_Intro_2015_Updates_hu_HU_20151209_153539\hu-HU\Internet_Anti-DrugIntro2015.xml_1457007.xlf" datatype="x-sdlfilterframework2" source-language="en-US" target-language="hu-HU"><body><trans-unit translate="no" id="c3a13bfb-ed51-49cf-8278-e2c86c2114c0"><source><x id="0"/></source></trans-unit><group><sdl:cxts><sdl:cxt id="1"/></sdl:cxts><trans-unit id="3b4520df-4483-4c9e-8a9b-ce2544269f3e"><source><x id="1"/>Drugs are robbing our children of their future. <x id="2"/>Every 17 seconds a teenager experiments with an illicit drug for the first time. <x id="3"/>And nearly half meet dealers right in the hallways and campuses of their schools. <x id="4"/>While at the same time prescription drug abuse has soared by 400%, <x id="5"/>exceeding heroin, cocaine and Ecstasy combined. <x id="6"/>Billions are spent on programs to reach kids, <x id="7"/>with little or no impact on teen experimentation. <x id="8"/>And all while drug-related crime and violence among young people <x id="9"/>continues to escalate, threatening their lives and the safety of their communities. <x id="10"/>But helping young people lead lives without drugs <x id="11"/>is the Foundation for a Drug-Free World, <x id="12"/>coordinating the largest non-governmental <x id="13"/>drug education and prevention campaign on Earth. <x id="14"/>Drawing on more than 25 years of experience in drug prevention, <x id="15"/>today Foundation volunteers and members of like-minded organizations <x id="16"/>conduct an international multi-media Truth About Drugs campaign. <x id="17"/>At the heart of the program is a series of high-impact educational booklets <x id="18"/>covering the most commonly abused drugs, <x id="19"/>educating youth so they can make their own decision about drugs. <x id="20"/>And as the materials are available in some 20 languages, <x id="21"/>Drug-Free World teams work everywhere – <x id="22"/>from cocaine distribution points in Southern Florida <x id="23"/>to neighborhoods overrun with meth in Southern California. <x id="24"/>From the crack streets of New York and Harlem <x id="25"/>to designer-drug routes of Australia and Asia <x id="26"/>and out to the cannabis trafficking lanes of Africa and Western Europe. <x id="27"/>Then there are the partnerships the Foundation forges everywhere else. <x id="28"/>The New York Drug-Free World formed an alliance <x id="29"/>with the New York City Department of Youth and Community Development, <x id="30"/>linking them to hundreds of schools and over a million students across New York City – <x id="31"/>from Brooklyn and the Bronx to Staten Island and Manhattan. <x id="32"/>All of which led to Drug-Free World being officially inaugurated into <x id="33"/>a New York State Senate Task Force on Prescription Drugs and Heroin – <x id="34"/>and this from the New York State Senate: <x id="35"/>“Drug-Free World has enriched our state and is worthy of the esteem of all New Yorkers.” <x id="36"/>In Indonesia, Drug-Free World Southeast Asia advances Truth About Drugs to Indonesian youth <x id="37"/>through the National Scouting Association and its membership of more than 20 million kids. <x id="38"/>Partnering with the Association’s Director for Education and Training, <x id="39"/>Drug-Free World provided 550,000 translated Truth About Drugs booklets, <x id="40"/>as well as documentaries, educator guides and lesson plans. <x id="41"/>Directly following this, more than 4,000 Senior Scout Trainers adopted Drug-Free World <x id="42"/>to simultaneously attack the plague of drug abuse in Indonesia and serve as agents of change for the nation. <x id="43"/>In Mexico City, Drug-Free World partners <x id="44"/>with the Auxiliary Security Forces for the State of Mexico, <x id="45"/>receiving more than 4,000 booklets pertaining to the principal drugs in their territory. <x id="46"/>They in turn deploy with precision, distributing literal truckloads of booklets all over the city <x id="47"/>which is how Drug-Free World infused nearly a quarter of a million booklets <x id="48"/>and thereby assisted the State of Mexico in a war against drugs. <x id="49"/>Booklet distribution is flanked by a series <x id="50"/>of award-winning public service announcements <x id="51"/>broadcast on hundreds of TV stations, <x id="52"/>totaling over 120 countries and reaching tens of millions of viewers. <x id="53"/>But the one component that distinguishes Drug-Free World <x id="54"/>from any other similarly aimed program is this one. <x id="55"/>An award-winning, full-length, hour-and-a-half documentary <x id="56"/>containing films on every drug of choice. <x id="57"/>This documentary educates and enlightens and speaks to kids in their own language. <x id="58"/>It’s told by people who know addiction firsthand and have actually “been there,” <x id="59"/>and by telling their stories they pass on what they learned <x id="60"/>so others can avoid going down the same path. <x id="61"/>Drug-Free World also provides the Truth About Drugs Education Package. <x id="62"/>It’s complete with posters, the documentary and PSAs, an educational guide, <x id="63"/>two dozen sets of the booklets – in other words, an entire curriculum <x id="64"/>with a teacher’s manual, a full semester of lesson plans, <x id="65"/>essays and homework assignments. <x id="66"/>And all of this is provided by the Foundation at no charge to educators. <x id="67"/>While to ensure the Truth About Drugs reaches everyone, <x id="68"/>there is drugfreeworld.org. <x id="69"/>When visitors arrive there, <x id="70"/>they discover the ultimate interactive drug resource center for educators, adults and kids. <x id="71"/>Here anyone can view and download the booklets, watch films and PSAs, <x id="72"/>create a virtual classroom or download the curriculum app <x id="73"/>and order resources to take the program even further. <x id="74"/>All told, it adds up to more than 72 million Truth About Drugs booklets distributed, <x id="75"/>tens of thousands of drug awareness events in 70 countries, <x id="76"/>some 2,000 alliances with other drug prevention entities, <x id="77"/>more than 17 million visits annually to the Drug-Free World website <x id="78"/>and hundreds ordering materials every week – <x id="79"/>bringing the total people reached with the Foundation’s drug-free message <x id="80"/>to more than 200 million in a single year. <x id="81"/>It <x id="82"/>is<x id="83"/> possible to reverse the trend of drug abuse in our society. <x id="84"/>The results of the Truth About Drugs program have been proven <x id="85"/>to effectively empower youth so they make the right choice. <x id="86"/>Anyone can help by supporting a Truth About Drugs program, <x id="87"/>or providing for distribution of educational materials <x id="88"/>to youth in their community or city. <x id="89"/>By joining the Foundation for a Drug-Free World’s campaign, <x id="90"/>we can help steer an entire generation away from drugs <x id="91"/>and set them on course for a drug-free future. </source><seg-source><mrk mtype="seg" mid="2"><x id="1"/>Drugs are robbing our children of their future. </mrk><mrk mtype="seg" mid="3"><x id="2"/>Every 17 seconds a teenager experiments with an illicit drug for the first time. </mrk><mrk mtype="seg" mid="4"><x id="3"/>And nearly half meet dealers right in the hallways and campuses of their schools. </mrk><mrk mtype="seg" mid="5"><x id="4"/>While at the same time prescription drug abuse has soared by 400%, <x id="5"/>exceeding heroin, cocaine and Ecstasy combined. </mrk><mrk mtype="seg" mid="6"><x id="6"/>Billions are spent on programs to reach kids, <x id="7"/>with little or no impact on teen experimentation. </mrk><mrk mtype="seg" mid="7"><x id="8"/>And all while drug-related crime and violence among young people <x id="9"/>continues to escalate, threatening their lives and the safety of their communities. </mrk><mrk mtype="seg" mid="8"><x id="10"/>But helping young people lead lives without drugs <x id="11"/>is the Foundation for a Drug-Free World, <x id="12"/>coordinating the largest non-governmental <x id="13"/>drug education and prevention campaign on Earth. </mrk><mrk mtype="seg" mid="9"><x id="14"/>Drawing on more than 25 years of experience in drug prevention, <x id="15"/>today Foundation volunteers and members of like-minded organizations <x id="16"/>conduct an international multi-media Truth About Drugs campaign. </mrk><mrk mtype="seg" mid="10"><x id="17"/>At the heart of the program is a series of high-impact educational booklets <x id="18"/>covering the most commonly abused drugs, <x id="19"/>educating youth so they can make their own decision about drugs. </mrk><mrk mtype="seg" mid="11"><x id="20"/>And as the materials are available in some 20 languages, <x id="21"/>Drug-Free World teams work everywhere – <x id="22"/>from cocaine distribution points in Southern Florida <x id="23"/>to neighborhoods overrun with meth in Southern California. </mrk><mrk mtype="seg" mid="12"><x id="24"/>From the crack streets of New York and Harlem <x id="25"/>to designer-drug routes of Australia and Asia <x id="26"/>and out to the cannabis trafficking lanes of Africa and Western Europe. </mrk><mrk mtype="seg" mid="13"><x id="27"/>Then there are the partnerships the Foundation forges everywhere else. </mrk><mrk mtype="seg" mid="14"><x id="28"/>The New York Drug-Free World formed an alliance <x id="29"/>with the New York City Department of Youth and Community Development, <x id="30"/>linking them to hundreds of schools and over a million students across New York City – <x id="31"/>from Brooklyn and the Bronx to Staten Island and Manhattan. </mrk><mrk mtype="seg" mid="15"><x id="32"/>All of which led to Drug-Free World being officially inaugurated into <x id="33"/>a New York State Senate Task Force on Prescription Drugs and Heroin – <x id="34"/>and this from the New York State Senate: <x id="35"/>“Drug-Free World has enriched our state and is worthy of the esteem of all New Yorkers.” </mrk><mrk mtype="seg" mid="16"><x id="36"/>In Indonesia, Drug-Free World Southeast Asia advances Truth About Drugs to Indonesian youth <x id="37"/>through the National Scouting Association and its membership of more than 20 million kids. </mrk><mrk mtype="seg" mid="17"><x id="38"/>Partnering with the Association’s Director for Education and Training, <x id="39"/>Drug-Free World provided 550,000 translated Truth About Drugs booklets, <x id="40"/>as well as documentaries, educator guides and lesson plans. </mrk><mrk mtype="seg" mid="18"><x id="41"/>Directly following this, more than 4,000 Senior Scout Trainers adopted Drug-Free World <x id="42"/>to simultaneously attack the plague of drug abuse in Indonesia and serve as agents of change for the nation. </mrk><mrk mtype="seg" mid="19"><x id="43"/>In Mexico City, Drug-Free World partners <x id="44"/>with the Auxiliary Security Forces for the State of Mexico, <x id="45"/>receiving more than 4,000 booklets pertaining to the principal drugs in their territory. </mrk><mrk mtype="seg" mid="20"><x id="46"/>They in turn deploy with precision, distributing literal truckloads of booklets all over the city <x id="47"/>which is how Drug-Free World infused nearly a quarter of a million booklets <x id="48"/>and thereby assisted the State of Mexico in a war against drugs. </mrk><mrk mtype="seg" mid="21"><x id="49"/>Booklet distribution is flanked by a series <x id="50"/>of award-winning public service announcements <x id="51"/>broadcast on hundreds of TV stations, <x id="52"/>totaling over 120 countries and reaching tens of millions of viewers. </mrk><mrk mtype="seg" mid="22"><x id="53"/>But the one component that distinguishes Drug-Free World <x id="54"/>from any other similarly aimed program is this one. </mrk><mrk mtype="seg" mid="23"><x id="55"/>An award-winning, full-length, hour-and-a-half documentary <x id="56"/>containing films on every drug of choice. </mrk><mrk mtype="seg" mid="24"><x id="57"/>This documentary educates and enlightens and speaks to kids in their own language. </mrk><mrk mtype="seg" mid="25"><x id="58"/>It’s told by people who know addiction firsthand and have actually “been there,” <x id="59"/>and by telling their stories they pass on what they learned <x id="60"/>so others can avoid going down the same path. </mrk><mrk mtype="seg" mid="26"><x id="61"/>Drug-Free World also provides the Truth About Drugs Education Package. </mrk><mrk mtype="seg" mid="27"><x id="62"/>It’s complete with posters, the documentary and PSAs, an educational guide, <x id="63"/>two dozen sets of the booklets – in other words, an entire curriculum <x id="64"/>with a teacher’s manual, a full semester of lesson plans, <x id="65"/>essays and homework assignments. </mrk><mrk mtype="seg" mid="28"><x id="66"/>And all of this is provided by the Foundation at no charge to educators. </mrk><mrk mtype="seg" mid="29"><x id="67"/>While to ensure the Truth About Drugs reaches everyone, <x id="68"/>there is drugfreeworld.org. </mrk><mrk mtype="seg" mid="30"><x id="69"/>When visitors arrive there, <x id="70"/>they discover the ultimate interactive drug resource center for educators, adults and kids. </mrk><mrk mtype="seg" mid="31"><x id="71"/>Here anyone can view and download the booklets, watch films and PSAs, <x id="72"/>create a virtual classroom or download the curriculum app <x id="73"/>and order resources to take the program even further. </mrk><mrk mtype="seg" mid="32"><x id="74"/>All told, it adds up to more than 72 million Truth About Drugs booklets distributed, <x id="75"/>tens of thousands of drug awareness events in 70 countries, <x id="76"/>some 2,000 alliances with other drug prevention entities, <x id="77"/>more than 17 million visits annually to the Drug-Free World website <x id="78"/>and hundreds ordering materials every week – <x id="79"/>bringing the total people reached with the Foundation’s drug-free message <x id="80"/>to more than 200 million in a single year. </mrk><mrk mtype="seg" mid="33"><x id="81"/>It <x id="82"/>is<x id="83"/> possible to reverse the trend of drug abuse in our society. </mrk><mrk mtype="seg" mid="34"><x id="84"/>The results of the Truth About Drugs program have been proven <x id="85"/>to effectively empower youth so they make the right choice. </mrk><mrk mtype="seg" mid="35"><x id="86"/>Anyone can help by supporting a Truth About Drugs program, <x id="87"/>or providing for distribution of educational materials <x id="88"/>to youth in their community or city. </mrk><mrk mtype="seg" mid="36"><x id="89"/>By joining the Foundation for a Drug-Free World’s campaign, <x id="90"/>we can help steer an entire generation away from drugs <x id="91"/>and set them on course for a drug-free future. </mrk></seg-source><target></target></trans-unit></group><trans-unit translate="no" id="7890462c-edcb-4fe6-9192-033ba76d9942"><source><x id="183"/></source></trans-unit></body></file></xliff> 
+0

пожалуйста, напишите упрощенный образец XML – har07

+0

@ har07 - я отправил образец XML, извините за задержку здесь – ib11

+0

ах я вижу, проверить последнее обновление моего ответа – har07

ответ

1

Что-то вроде этого

string[] parentids = xliff.Descendants() 
    .Elements(xmlns + "trans-unit") 
    .Elements(xmlns + "seg-source") 
    .Elements(xmlns + "mrk") 
    .Where(e => e.Attribute("mtype").Value == "seg") 
    .Select(item => (XElement)item.Parent.Parent.PreviousNode) 
     .Where(item => item != null) 
     .Select(item => item.Elements(xmlns + "source") 
     .Elements(xmlns + "x") 
     .LastOrDefault() 
     .Attribute("id") 
     .Value.ToString()).ToArray(); 
+0

См. Обновленное выражение – Artem

+0

Хм. Это 'Where' дает ошибку компилятора:« System.Xml.Linq.XElement »не содержит определения для« Where »и никакого метода расширения« Where », принимающий первый аргумент типа« System.Xml.Linq.XElement », может (вы не указали директиву использования или ссылку на сборку?) – ib11

+1

извините, попробуйте это – Artem

0

Вы можете попробовать этот способ:

var parentids = xliff.Descendants() 
        .Elements(xmlns + "trans-unit") 
        .Where(o => o.Elements(xmlns + "seg-source") 
            .Elements(xmlns + "mrk") 
            .Any(e => (string)e.Attribute("mtype") == "seg")) 
        .Select(o => (XElement)o.PreviousNode) 
        .Elements(xmlns + "source") 
        .Elements(xmlns + "x") 
        .Select(o => (string)o.Attribute("id")); 
+0

Спасибо. Я добавил образец xml сейчас. Предыдущий узел - это еще одна «транс-единица» (предыдущий узел родителя родителя). – ib11

+0

@ ib11 проверить обновленный ответ :) – har07

+0

спасибо за обновление. Ага! это теперь возвращает массив из 3 элементов (мне пришлось добавить 'ToArray' в конце, иначе он дал мне ошибку компиляции. Но на самом деле существует 16' mrk' с атрибутом 'seg', поэтому он должен дать мне длину 16 массив. Знаете что? Я вставляю полный XML, просто чтобы уменьшить боль здесь.Это может помочь решить тупик. (он будет неформатирован). – ib11

0

Мне не нравится предыдущий, реальный некрасиво. Попробуйте это, когда вы не получите никаких значений.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 
      XDocument doc = XDocument.Load(FILENAME); 
      XElement xliff = (XElement)doc.FirstNode; 
      XNamespace ns = xliff.Name.Namespace; 
      var testid = xliff.Descendants(ns + "trans-unit").Where((x, i) => (i % 2) == 0).Select(y => new { 
        x = y.Descendants(ns + "x") 
        .Select(z => z.Attribute("id").Value) 
        .Last() 
      }).ToList(); 

     } 
    } 
} 
+0

Ничего себе, не могли бы вы помочь мне и указать мне, где я могу изучить, что означает выражение 'Where'? Также, пожалуйста, см. Мое новое сообщение: [http://stackoverflow.com/questions/36927046/c-sharp-linq-xml-parsing-using-previousnode](http://stackoverflow.com/questions/36927046/c- sharp-linq-xml-parsing-using-previousnode) – ib11

+0

Обычно я использую эту веб-страницу: https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b. (X, i) можно использовать с Select или Where, а x - как обычный select/where, а i - индекс, как в цикле for. – jdweng

+0

Удивительный, спасибо большое! Наверное, вы видели меня с другого поста с тех пор ... Я вижу, могу ли я построить ваше предложение там. (На данный момент я сначала тестирую XML, чтобы увидеть, какую версию и затем выполнить либо один из двух типов запросов.) – ib11