如何在C#中从xml中提取部分属性值

时间:2017-08-14 22:21:46

标签: xml xslt c#-4.0

我只需要在属性“PointName”中提取“:”和“/”之间的部分。 以下是XML示例:

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

我目前正在使用以下代码:

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();

我不想在pointNames上使用循环,因为在XML中tblPoint节点的数量可能是数千个。

2 个答案:

答案 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

答案 1 :(得分:0)

使用michael.hor257k's样式表的略微修改(我使用&#39;。&#39;字符作为分隔符,因为我无法使新行工作):

//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

如果我们能够使换行符起作用,那么它将更有效率,因为我们不需要读取代表转换的整个字符串。