2017-08-14 35 views
0

我只需要提取屬性「PointName」中':'和'/'之間的部分。 下面是示例XML:如何從C#中的xml中提取屬性值的一部分

var xdoc = XDocument.Load(xmlFilePath); // xmlFilePath - where the above XML file is located. 
var ns = XNamespace.Get("Data"); 
var pointNames = xdoc.Root.Elements(ns + "tblPoint").Attributes("PointName").ToList(); 

我希望有一種方式來填充這樣的pointNames:

var pointNames = xdoc.Root.Elements(ns + "tblPoint").Attributes("PointName").StringBetween(':', '/').ToList(); 

<?xml version="1.0" encoding="utf-8"?> 
<Trend xmlns="Data"> 
<tblPoint PointName="ABC:XYZ123/AAA.DDD-111.MMM.MV-3.PV" UOM="0"> 
     <tblValue UTCDateTime="2017-07-18T05:07:47" val="3" /> 
     <tblValue UTCDateTime="2017-07-18T05:08:27" val="0" /> 
</tblPoint> 
<tblPoint PointName="BCD:XYZ234/AAA.DDD-222.MMM.MV-3.PV" UOM="0"> 
     <tblValue UTCDateTime="2017-07-18T06:01:12" val="0" /> 
     <tblValue UTCDateTime="2017-07-18T06:01:13" val="0" /> 
</tblPoint> 
</Trend> 
我目前使用下面的代碼

我不願意在pointNames上使用循環,因爲tblPoint節點在XML中可以有數千個節點。

+0

爲什麼標記爲XSLT? –

+0

我相信這個問題可以通過使用XSLT更好地解決。 –

回答

0

使用michael.hor257k's樣式表的我稍微修改(」 m使用'。'字符作爲分隔符,因爲我無法獲得換行符):

//A static field defined in some class 
static readonly xsl = @" 

<xsl:stylesheet version=""1.0"" 
xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"" 
xmlns:d=""Data""> 
<xsl:output method=""text""/> 

<xsl:template match=""/d:Trend""> 
    <xsl:for-each select=""d:tblPoint""> 
     <xsl:value-of select=""substring-before(substring-after(@PointName, ':'), '/')"" /> 
     <xsl:text disable-output-escaping=""yes"">.</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 


</xsl:for-each> 
</xsl:template> 

</xsl:stylesheet>".Trim(); 

然後,在一些方法:

var xsldoc = XDocument.Load(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(xsl))); 
var xslt = new System.Xml.Xsl.XslCompiledTransform(); 
var ms = new MemoryStream(); 

xslt.Load(xsldoc.CreateReader());  
xslt.Transform(xdoc.CreateReader(), null, ms); //xdoc is your XML document that you loaded. 
ms.Position = 0; 

var sr = new StreamReader(ms); 

var xs = sr.ReadToEnd().Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); 

foreach (var x in xs) 
    Console.WriteLine(x); 

輸出是:

XYZ123 
XYZ234 

如果我們能換行的工作,那麼這將是更有效,因爲我們不會需要讀取表示變換的整個字符串。

+0

像魅力一樣工作,謝謝! –

0

這是相當瑣碎的XSLT做的事情 - 嘗試:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:d="Data"> 
<xsl:output method="text"/> 

<xsl:template match="/d:Trend"> 
    <xsl:for-each select="d:tblPoint"> 
     <xsl:value-of select="substring-before(substring-after(@PointName, ':'), '/')" /> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 

</xsl:stylesheet> 

結果

XYZ123 
XYZ234 
+0

太棒了!你知道如何在C#中使用XSLT解決方案嗎?或者你只是一個XSLT專家? :) –

+0

恐怕我對C#一無所知(儘管我會認爲這是你可以在幾分鐘內發現的東西)。 –