使用"PreviousNode"解析C#LINQ xml;

编程入门 行业动态 更新时间:2024-10-09 16:30:37
本文介绍了使用"PreviousNode"解析C#LINQ xml;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

在SO的帮助下,我设法整理了以下LINQ表达式.

With quite some help from SO, I managed to put together the following LINQ expression.

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();

它的作用是找到一个mrk标记(具有@mtype="seg"),然后升至trans-unit祖先(.parent.parent),并检查先前的同级trans-unit是否具有子元素trans,如果不是,则从source子元素返回最后一个x元素的@id,否则返回null(必须返回null,不能不返回匹配项).

What it does is that it locates a mrk tag (that has @mtype="seg") and then it goes up to the trans-unit ancestor (.parent.parent) and checks if the previous sibling trans-unit has a child trans and if not, it returns from the source child the @id of the last x element, otherwise it returns null (it must return null, cannot just not return match).

我需要补充一点,尽管下面的示例中只有一个这样的先前节点,没有trans元素,但在现实生活中xml中还有很多,因此我必须使用PreviousNode.

I need to add that while the below samples only have one such previous node with no trans element, in the real life xml there are many more, so I must use PreviousNode.

这是它可以使用的XML,并完美地返回"2":

Here is the XML it works with, and returns "2" perfectly:

<?xml version="1.0" encoding="utf-8"?> <xliff xmlns:sdl="sdl/FileTypes/SdlXliff/1.0" version="1.2" sdl:version="1.0" xmlns="urn:oasis:names:tc:xliff:document:1.2"> <file original="Pasadena_Internet_2016.xml" source-language="en-US" datatype="x-sdlfilterframework2" target-language="da-DK"> <body> <trans-unit id="d679cb2d-ecba-47ba-acb7-1bb4a798c755" translate="no"> <source> <x id="0" /> <x id="1" /> <x id="2" /> </source> </trans-unit> <trans-unit id="aed9fde2-fd1b-4eba-bfc9-06d325aa7047"> <source> <x id="3" />Pasadena, California’s iconic Colorado Boulevard <x id="4" />has been the site of the world-famous Tournament of Roses Parade since it began in 1890. </source> <seg-source> <mrk mtype="seg" mid="1"> <x id="3" />Pasadena, California’s iconic Colorado Boulevard <x id="4" />has been the site of the world-famous Tournament of Roses Parade since it began in 1890. </mrk> </seg-source> <target> <mrk mtype="seg" mid="1"> <x id="3" /><x id="4" />Pasadena, Californiens ikoniske Colorado Boulevard har været stedet for den verdensberømte Rose Bowl-parade siden den begyndte i 1890. </mrk> </target> </trans-unit> </body> </file> </xliff>

问题是我需要解决的最后一步是存在另一种类型的XML,其注视trans-unit封装在另一个XML中不存在的另一个group元素中.因此,这里还有一个父级可以向上跳转并获得前一个trans-unit兄弟姐妹,就在group之前.

The problem is that I need to solve as a last step is that there is another type of XML that has the staring trans-unit encapsulated within another group element that is not present in the other XML. So here there is one more parent to jump upwards and get the previous trans-unit sibling, right before the group.

我正在尝试将其构建到相同的LINQ表达式中,以便它可以处理两种情况.

I am trying to build this into the same LINQ expression so it handles both scenarios.

实际上,如果我将第6行修改为此,那么它将起作用:

In fact if I modify the line 6 to this, then it works:

.Select(item => (XElement)item.Parent.Parent.Parent.PreviousNode) <!-- ^------ additional Parent -->

这是另一个上面的代码现在引发异常的XML,但是它应该返回"0":

Here is the other XML that right now throws an exception with the above code, but it should return "0":

<?xml version="1.0" encoding="utf-8"?> <xliff xmlns:sdl="sdl/FileTypes/SdlXliff/1.0" xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2" sdl:version="1.0"> <file original="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"/> </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> </seg-source> <target> <mrk mtype="seg" mid="2"> <x id="1"/>A drogok megfosztják gyermekeinket a jövőjüktől. </mrk> <mrk mtype="seg" mid="3"> <x id="2"/>17 másodpercenként egy újabb tizenéves próbálja ki először a kábítószereket. </mrk> </target> </trans-unit> </group> <trans-unit translate="no" id="7890462c-edcb-4fe6-9192-033ba76d9942"> <source> <x id="183"/> </source> </trans-unit> </body> </file> </xliff>

我将不胜感激任何帮助.

I will be more than appreciative for any help.

推荐答案

您可以尝试使用Ancestors().Last()查找名为的最高级别祖先,而不是根据XML结构多次使用Parent导航XML树. "trans-unit"或"group",然后导航到上一个节点.

Instead of navigating up the XML tree using Parent several times depending on the XML structure, you can try using Ancestors().Last() to find the highest level ancestor named either "trans-unit" or "group", and then navigate to the previous node.

尝试替换此部分:

.Select(item => (XElement) item.Parent.Parent.PreviousNode)

与此:

.Select(item => (XElement)item.Ancestors() .Last(o => new[]{"trans-unit","group"}.Contains(o.Name.LocalName)) .PreviousNode)

更多推荐

使用"PreviousNode"解析C#LINQ xml;

本文发布于:2023-06-10 18:40:45,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/616543.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:PreviousNode   quot   xml   LINQ

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!