C# 在测试节点是否缺少元素时获取 XML 中上一个节点的 child 的特定属性
C# getting a specific attribute of a child of a Previous node in XML while testing the node for a missing element
我有一个 xliff
,我正在尝试获取前一个 [=19] 中 source
的最后一个 x
元素的 id
属性的值=] 只要它没有 target
child.
所以非常具体,我不仅需要 return 所有元素,还需要获取 parent 节点,测试前一个是否有 target
元素,如果有 return null
,但如果没有则 return id
最后一个 child x
属性的值 source
=]元素.
更新: xliff中有很多trans-units
,下面只是一个片段。我根据 <mrk mtype="seg" mid="6">
元素(使用其 mid
属性)找到一个特定的,然后如果没有目标,我需要获取前一个节点的 child。
这里是 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 -->
</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>
所以在这种情况下,我想要 "12"
returned。如果有目标,我应该得到 null
.
我设法 return 使用以下代码行的整个节点,但我似乎无法到达 children:
xliff = XDocument.Load(Path.GetFullPath(FilePath));
XNamespace xmlns = "urn:oasis:names:tc:xliff:document:1.2";
XNamespace ns = "http://sdl.com/FileTypes/SdlXliff/1.0";
string testid = xliff.Descendants()
.Elements(xmlns + "trans-unit")
.Elements(xmlns + "seg-source")
.Elements(xmlns + "mrk")
.Where(e => e.Attribute("mtype").Value == "seg" && e.Attribute("mid").Value == SegId)
.FirstOrDefault().Parent.Parent.PreviousNode.ToString();
这个return是前面的节点好吧,但是后来代码更进一步,我有这个,但是这个抛出异常:
string testid = xliff.Descendants()
.Elements(xmlns + "trans-unit")
.Elements(xmlns + "seg-source")
.Elements(xmlns + "mrk")
.Where(e => e.Attribute("mtype").Value == "seg" && e.Attribute("mid").Value == SegId)
.Select(n => n.Parent.Parent.PreviousNode as XElement)
.Where(c => c.Elements(xmlns + "target") == null && c.Elements(xmlns + "source").Elements(xmlns + "x").Last().Value != null)
.FirstOrDefault().Attribute("id").Value;
有人可以帮忙吗?
这个有效
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 => x.Element(ns + "target") == null)
.Descendants(ns + "x")
.Select(y => y.Attribute("id").Value)
.Last();
}
}
}
我终于想出了下面的代码,它完全符合我的要求,但我认为应该有一种使用 LINQ 的更流畅的方法:
XElement testid = xliff.Descendants()
.Elements(xmlns + "trans-unit")
.Elements(xmlns + "seg-source")
.Elements(xmlns + "mrk")
.Where(e => e.Attribute("mtype").Value == "seg" && e.Attribute("mid").Value == SegId).FirstOrDefault();
if (testid.Parent.Parent.PreviousNode.ToString().IndexOf("<target>") > 0)
{
return null;
}
else
{
var strid = xliff.Descendants()
.Select(e => testid.Parent.Parent.PreviousNode as XElement)
.Elements(xmlns + "source")
.Elements(xmlns + "x")
.LastOrDefault()
.Attribute("id")
.Value.ToString();
return strid;
}
我有一个 xliff
,我正在尝试获取前一个 [=19] 中 source
的最后一个 x
元素的 id
属性的值=] 只要它没有 target
child.
所以非常具体,我不仅需要 return 所有元素,还需要获取 parent 节点,测试前一个是否有 target
元素,如果有 return null
,但如果没有则 return id
最后一个 child x
属性的值 source
=]元素.
更新: xliff中有很多trans-units
,下面只是一个片段。我根据 <mrk mtype="seg" mid="6">
元素(使用其 mid
属性)找到一个特定的,然后如果没有目标,我需要获取前一个节点的 child。
这里是 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 -->
</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>
所以在这种情况下,我想要 "12"
returned。如果有目标,我应该得到 null
.
我设法 return 使用以下代码行的整个节点,但我似乎无法到达 children:
xliff = XDocument.Load(Path.GetFullPath(FilePath));
XNamespace xmlns = "urn:oasis:names:tc:xliff:document:1.2";
XNamespace ns = "http://sdl.com/FileTypes/SdlXliff/1.0";
string testid = xliff.Descendants()
.Elements(xmlns + "trans-unit")
.Elements(xmlns + "seg-source")
.Elements(xmlns + "mrk")
.Where(e => e.Attribute("mtype").Value == "seg" && e.Attribute("mid").Value == SegId)
.FirstOrDefault().Parent.Parent.PreviousNode.ToString();
这个return是前面的节点好吧,但是后来代码更进一步,我有这个,但是这个抛出异常:
string testid = xliff.Descendants()
.Elements(xmlns + "trans-unit")
.Elements(xmlns + "seg-source")
.Elements(xmlns + "mrk")
.Where(e => e.Attribute("mtype").Value == "seg" && e.Attribute("mid").Value == SegId)
.Select(n => n.Parent.Parent.PreviousNode as XElement)
.Where(c => c.Elements(xmlns + "target") == null && c.Elements(xmlns + "source").Elements(xmlns + "x").Last().Value != null)
.FirstOrDefault().Attribute("id").Value;
有人可以帮忙吗?
这个有效
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 => x.Element(ns + "target") == null)
.Descendants(ns + "x")
.Select(y => y.Attribute("id").Value)
.Last();
}
}
}
我终于想出了下面的代码,它完全符合我的要求,但我认为应该有一种使用 LINQ 的更流畅的方法:
XElement testid = xliff.Descendants()
.Elements(xmlns + "trans-unit")
.Elements(xmlns + "seg-source")
.Elements(xmlns + "mrk")
.Where(e => e.Attribute("mtype").Value == "seg" && e.Attribute("mid").Value == SegId).FirstOrDefault();
if (testid.Parent.Parent.PreviousNode.ToString().IndexOf("<target>") > 0)
{
return null;
}
else
{
var strid = xliff.Descendants()
.Select(e => testid.Parent.Parent.PreviousNode as XElement)
.Elements(xmlns + "source")
.Elements(xmlns + "x")
.LastOrDefault()
.Attribute("id")
.Value.ToString();
return strid;
}