Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 值吞没了嵌入的XML_C#_Xml_Linq_Xml Parsing - Fatal编程技术网

C# 值吞没了嵌入的XML

C# 值吞没了嵌入的XML,c#,xml,linq,xml-parsing,C#,Xml,Linq,Xml Parsing,我的问题是: 我正在将一堆我几乎无法控制的基于XML的日志解析为MySQL语句,以便从基于XML的数据库切换到MySQL。这一点把我难住了 如果我查看包含我感兴趣的字符串的IEnumerable,我可以看到嵌入的XML语句。但是,如果我获取该字符串的值,XML语句将消失。例如: IEnumerable可见: <StepDetails>Set input voltage to 2.80V WDT should allow CPU power. CPU should detect Po

我的问题是: 我正在将一堆我几乎无法控制的基于XML的日志解析为MySQL语句,以便从基于XML的数据库切换到MySQL。这一点把我难住了

如果我查看包含我感兴趣的字符串的IEnumerable,我可以看到嵌入的XML语句。但是,如果我获取该字符串的值,XML语句将消失。例如:

IEnumerable可见:

<StepDetails>Set input voltage to 2.80V WDT should allow CPU power.  CPU should detect PowerFail signal and output a<PowerFail /> tag to the serial line.  WDT should reset every 1.6 seconds</StepDetails>
如果我做了一个。ToString,我也会得到同样的结果

程序: 如果您将以下内容作为C语句粘贴到LinqPad中,您就会明白我的意思。XML标记消失。我注意到它也会消失在这里,除非我在它周围放回蜱虫。我加入了LinqPad标签,因为我就是这样解析这些文件的。几年前,有成千上万的日志文件使用一系列LinqPad脚本将日志处理到MySQL中,并插入它们以创建新的数据库

我的问题: 我意识到我可以用一些正则表达式或子字符串之类的东西来获取字符串,但是看起来我应该能够从IEnumerable中获取整个字符串、标记&但是如何做到呢?另外,我很想知道为什么标签被吞下只是为了我的启发

我有大约三十多种不同类型的日志异常,影响了我昨天修复的上万条日志,仅在七年左右的数据中就应用了1500多条日志,因此我想找到一个更通用的解决方案,而不是针对每个日志的XML标记特定的正则表达式、子字符串或其他任何内容。我无法更改日志,而且我不想在传输到新数据库时丢失数据

要直接查看问题,请执行以下操作: 剪切并粘贴到as C语句中有没有类似于JSFIDLE for JavaScript的在线方式?我在底部添加了一个regex解决方案,以防有人来寻找类似的东西,但我仍然对更好的方法感兴趣

string xml = @"<StepResults>
<TestStep Name='2.8V OPERATION' Result='Pass'>
    <OperatorComment/>
    <StepDetails>Set input voltage to 2.80V WDT should allow CPU power.  CPU should detect PowerFail signal and output a<PowerFail/> tag to the serial line.  WDT should reset every 1.6 seconds</StepDetails>
    <Measurements NumberOfMeasurements='1'>
        <Measurement Name='BATTERY VOLTAGE: VOLTS'>
            <MeasuredValue>2.794608</MeasuredValue>
            <Min>2.785000</Min>
            <Max>2.800000</Max>
        </Measurement>
    </Measurements>
</TestStep>
</StepResults>";
var xd = XDocument.Parse(xml);
Console.WriteLine(xd);

var xe = 
    from e in xd.Descendants("StepDetails")
    select e;
Console.WriteLine(xe);
Console.WriteLine(xe.First().Value);

//new code below to show a working regex solution:

string stepDetail = xe.First().ToString();
Regex matchFrontTag = new Regex("^<[^>]*>");
Regex matchRearTag = new Regex("<[^>]*>$");

stepDetail = matchFrontTag.Replace(stepDetail,string.Empty);
stepDetail = matchRearTag.Replace(stepDetail,string.Empty);

Console.WriteLine(stepDetail);
正如政府所说:

获取或设置此元素的连接文本内容

因此,XElement.Value实际上只返回文本节点,在混合内容的情况下,将忽略非文本节点,但不忽略其中包含的文本节点

您正在寻找XElement的内部XML,您可以使用XmlReader获得它

// this writes only the (concatenated) text nodes
Console.WriteLine(xe.First().Value);

// this writes the inner XML, including elements
var reader = xe.First().CreateReader();
reader.MoveToContent();
Console.WriteLine(reader.ReadInnerXml());
如果希望留在LINQ中,只需连接所有子节点的字符串表示:

Console.WriteLine(
  xe.First().Nodes().Aggregate("", (result, node) => result += node.ToString())
);


但正如链接的问题所说:这比使用阅读器要慢得多。

如果我理解正确,您正在寻找XElement的InnerXml。在这种情况下,请参阅以下问题:共享工作C代码片段的在线工具:dotnetfiddle.net和csharpad.com。感谢您的帮助,Frank,我暂时使用您的第一个LINQ one liner。如果这被证明是一个时间打击,我会调查的读者,而不是。
Console.WriteLine(
  xe.First().Nodes().Aggregate("", (result, node) => result += node.ToString())
);
string.Join("", xe.First().Nodes().Select(n => n.ToString())).Dump();