簡體   English   中英

使用“PreviousNode”解析C#LINQ xml

[英]C# LINQ xml parsing using “PreviousNode”

在SO的幫助下,我設法將以下LINQ表達式組合在一起。

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@id返回最后一個x元素的@id ,否則返回null (它必須返回null,不能只返回匹配)。

我需要補充說,雖然下面的示例只有一個這樣的前一個節點沒有trans元素,但在現實生活中xml還有更多,所以我必須使用PreviousNode

這是它使用的XML,並完美地返回"2"

<?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">
  <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封裝在另一個group元素中,而另一個group元素中沒有其他XML。 所以這里還有一個父母向上跳,並在group之前獲得之前的trans-unit兄弟。

我正在嘗試將其構建到相同的LINQ表達式中,以便它處理這兩種情況。

事實上,如果我修改第6行,那么它的工作原理是:

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

這是現在使用上面的代碼拋出異常的另一個XML,但它應該返回"0"

<?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="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>

我會非常感謝任何幫助。

您可以嘗試使用Ancestors().Last()來查找名為"trans-unit""group"的最高級祖先,而不是使用Parent多次導航XML樹,具體取決於XML結構,然后導航到上一個節點。

嘗試替換此部分:

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

這一個:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM