xslt - How to extract part of an attribute value from xml in C# -
i need extract part between ':' , '/' in attribute "pointname". following sample 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>
i'm using following code:
var xdoc = xdocument.load(xmlfilepath); // xmlfilepath - above xml file located. var ns = xnamespace.get("data"); var pointnames = xdoc.root.elements(ns + "tblpoint").attributes("pointname").tolist();
i wish there way populate pointnames this:
var pointnames = xdoc.root.elements(ns + "tblpoint").attributes("pointname").stringbetween(':', '/').tolist();
i hate use loop on pointnames because tblpoint nodes can thousands in number in xml.
using slight modification of michael.hor257k's stylesheet (i'm using '.' character delimiter since couldn't newlines work):
//a static field defined in 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();
then, in method:
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 xml document 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);
output is:
xyz123 xyz234
if can newlines work, more efficient since won't need read in entire string representing transform.
Comments
Post a Comment