c#使用XDocument再次解析xml

时间:2016-04-26 03:42:54

标签: c# arrays xml xpath linq-to-xml

我已经查看过很多帮助文件和很多类似的问题,但是我无法比返回后代集合更进一步。

我想要实现的是获取一个数组,其中包含idtag个孩子的ph元素的所有bpt属性的值(不是那些在st

的XPath中有xliff\file\header\tag-defs)的人

这是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">
<file original="\\txl-app1\scncontent\AUDIO\en\Testing\SubtitleXML-FTS\13Mar16_Game.xml" source-language="en-US" datatype="x-sdlfilterframework2" target-language="da-DK">
<header>
  <reference>
    <internal-file form="base64"></internal-file>
  </reference>
  <sdl:ref-files>
    <sdl:ref-file uid="0" id="http://www.sdl.com/Sdl.FileTypeSupport.Native.Xml/OriginalXmlFile" name="DF44_13Mar16_Speech_BirthdayGame.xml" o-path="\\txl-app1\scncontent\AUDIO\en\Testing\SubtitleXML-FTS\13Mar16_Speech_BirthdayGame.xml" date="04/25/2016 18:55:53" descr="The original XML file." expected-use="Generation" />
  </sdl:ref-files>
  <file-info xmlns="http://sdl.com/FileTypes/SdlXliff/1.0">
    <value key="SDL:FileId">c6550fcb-8e69-428a-a0a8-6447918a97a2</value>
    <value key="SDL:CreationDate">04/25/2016 16:16:55</value>
    <value key="SDL:OriginalFilePath">\\txl-app1\content\Testing\SubtitleXML-FTS\13Mar16_Game.xml</value>
    <value key="SDL:InputFilePath">\\txl-app1\content\en\Testing\SubtitleXML-FTS\13Mar16_Game.xml</value>
    <value key="SDL:OriginalEncoding">utf-8</value>
    <value key="HasUtf8Bom">true</value>
    <value key="IsFragment">false</value>
    <value key="SchemaLocation"></value>
    <value key="SDL:AutoClonedFlagSupported">True</value>
    <value key="xmlDeclaration">true</value>
    <value key="SDLWS:AssetId">1489743</value>
    <value key="SDLWS:DocId">3043144</value>
    <value key="SDLWS:TaskId">1382715</value>
    <value key="SDLWS:ScopingMode">0</value>
    <value key="SDLWS:CreationDate">2016-04-26T00:16:55Z</value>
    <value key="SDLWS:ProjectName">SubtitleXML-FTS_da_DK_20160425_111419</value>
    <value key="SDLWS:UserName">BI</value>
    <value key="ParagraphTextDirections"></value>
    <sniff-info>
      <detected-encoding detection-level="Certain" encoding="utf-8" />
      <detected-source-lang detection-level="Guess" lang="en-US" />
      <props>
        <value key="HasUtf8Bom">true</value>
        <value key="IsFragment">false</value>
        <value key="SchemaLocation"></value>
        <value key="xmlDeclaration">true</value>
      </props>
    </sniff-info>
  </file-info>
  <sdl:filetype-info>
    <sdl:filetype-id>Custom XML v 1.2.0.0 (WS:SubtitleXML-FTS)</sdl:filetype-id>
  </sdl:filetype-info>
  <fmt-defs xmlns="http://sdl.com/FileTypes/SdlXliff/1.0">
    <fmt-def id="1">
      <value key="Italic">True</value>
      <value key="TextColor">Black</value>
    </fmt-def>
  </fmt-defs>
  <tag-defs xmlns="http://sdl.com/FileTypes/SdlXliff/1.0">
    <tag id="7">
      <bpt name="i" seg-hint="Include" word-end="false">&lt;i&gt;</bpt>
      <ept name="i" word-end="false">&lt;/i&gt;</ept>
      <fmt id="1" />
    </tag>
    <tag id="3">
      <ph name="Sub" seg-hint="Include">&lt;Sub tc="01:05:00:08 01:05:04:26" WidthAllowed="75"/&gt;</ph>
    </tag>
    <tag id="4">
      <ph name="Sub" seg-hint="Include">&lt;Sub tc="01:05:05:00 01:05:08:24" WidthAllowed="60"/&gt;</ph>
    </tag>
    <tag id="5">
      <ph name="Sub" seg-hint="Include">&lt;Sub tc="01:05:08:28 01:05:13:04" WidthAllowed="60"/&gt;</ph>
    </tag>
    <tag id="6">
      <ph name="Sub" seg-hint="Include">&lt;Sub tc="01:05:13:08 01:05:17:22" WidthAllowed="60"/&gt;</ph>
    </tag>
    <tag id="8">
      <ph name="Sub" seg-hint="Include">&lt;Sub tc="01:05:17:26 01:05:22:11" WidthAllowed="60"/&gt;</ph>
    </tag>
    <tag id="9">
      <ph name="Sub" seg-hint="Include">&lt;Sub tc="01:05:21:21 01:05:27:13" WidthAllowed="90"/&gt;</ph>
    </tag>
    <tag id="10">
      <ph name="Sub" seg-hint="Include">&lt;Sub tc="01:05:27:17 01:05:33:02" WidthAllowed="75"/&gt;</ph>
    </tag>
    <tag id="13">
      <ph name="zwnj" word-end="false" seg-hint="Include">&lt;zwnj dir="1" spc="20"/&gt;</ph>
    </tag>
    <tag id="16">
      <ph name="Sub" seg-hint="Include">&lt;Sub tc="01:41:20:04 01:41:21:24" WidthAllowed="30"/&gt;</ph>
    </tag>
    <tag id="0">
      <st>&lt;XMLsubtitlefile"&gt;</st>
    </tag>
    <tag id="1">
      <st>&lt;Subtitles&gt;</st>
    </tag>
    <tag id="2">
      <st>&lt;NonVOsubs&gt;</st>
    </tag>
    <tag id="11">
      <st>&lt;/NonVOsubs&gt;</st>
    </tag>
    <tag id="12">
      <st>&lt;VOsub tc="01:41:01:17 01:41:09:27" WidthAllowed="120"&gt;</st>
    </tag>
    <tag id="14">
      <st>&lt;/VOsub&gt;</st>
    </tag>
    <tag id="15">
      <st>&lt;NonVOsubs&gt;</st>
    </tag>
    <tag id="17">
      <st>&lt;/NonVOsubs&gt;</st>
    </tag>
    <tag id="18">
      <st>&lt;/Subtitles&gt;</st>
    </tag>
    <tag id="19">
      <st>&lt;/XMLsubtitlefile&gt;</st>
    </tag>
  </tag-defs>
</header>
<body>...

代码方面我尝试了不同的版本,但这就是我所处的位置:

private static XDocument xliff;

public static List<XElement> GetTagArray(string FilePath)
{
    xliff = XDocument.Load(Path.GetFullPath(FilePath));
    XNamespace ns = "http://sdl.com/FileTypes/SdlXliff/1.0";
    var elements = xliff.Descendants().Elements(ns + "tag-defs").Elements().Select(e => e.Elements(ns + "ph")).ToList();

//and here I am stuck as not matter what I do above it returns empty...

}

感谢您提前提供任何帮助。

2 个答案:

答案 0 :(得分:1)

未经测试的代码,但请尝试以下内容:

XNamespace sdl = @"http://sdl.com/FileTypes/SdlXliff/1.0";
XNamespace ns = @"urn:oasis:names:tc:xliff:document:1.2";
foreach (var tag in xliff.Descendants(sdl + "tag"))
{
    foreach (var ph in tag.Elements(sdl + "ph"))
    {
        // Code here to process
    }
}

答案 1 :(得分:1)

在Jesse Good的帮助下解决方案是:

private static XDocument xliff;

public static int[] GetTagArray(string FilePath)
{
    xliff = XDocument.Load(Path.GetFullPath(FilePath));
    XNamespace ns = "http://sdl.com/FileTypes/SdlXliff/1.0";
    int[] elements = xliff.Descendants().Elements(ns + "tag-defs").Elements(ns + "tag").Elements(ns + "ph").Select(e => Int32.Parse(e.Parent.Attribute("id").Value)).ToArray();
    int[] elements2 = xliff.Descendants().Elements(ns + "tag-defs").Elements(ns + "tag").Elements(ns + "bpt").Select(e => Int32.Parse(e.Parent.Attribute("id").Value)).ToArray();

    int[] intarray = elements.Concat(elements2).ToArray();
    Array.Sort(intarray);

    return intarray;
}