2017-02-14 7 views
1

私はXamarin.FormsでSVGファイルを扱っています。これらのファイルは非常にシンプルで、単一の図形が含まれ、この図形は通常polylineになります。しかし、いくつかの点ベースの形状の1つが存在する可能性のあるエッジケースがあります。これらのファイルを解析するときに、shape要素の特定の属性の値を取得しようとしています。実行時まで必要なXElement名がわからない場合、XDocumentから属性値を取得する方法はありますか?

<svg width="1200" height="800" version="1.1" bordercolor="#666666" borderopacity="1.0" xmlns="http://www.w3.org/2000/svg"> 
    <polyline stroke="#004976" fill="transparent" stroke-width="5" points="479,91 ..." /> 
</svg> 

をだから私はpolylineためpoints属性の値を取得しようとしています。この最も一般的なケースで:ここ

は私がパースされることを期待するものの一例です。私はこれがLINQ-to-XMLの単純な関数になると確信していますが、私はそれを見逃しています。私はこれにはいくつかのバージョンを試してみました

public static Point[] GetPointsFromSVG(XDocument svg) 
{ 
    XElement shape = svg.Descendants().First(); 
    string pointsValue = shape.Attribute("points").Value; 

    var points = pointsValue.Split(' ').Select(x => x.Split(',')) 
          .Select(y => new Point(int.Parse(y[0]), int.Parse(y[1]))) 
          .ToArray(); 

    return points; 
} 

が、それぞれの場合にshapeXDocumentオブジェクトが有効かつ適切にフォーマットされていてもnullである:ここでは、私がこれまでにしようとしているものです。私はこのアプローチに結婚していないことに注意してください、私はただ動作するものが必要です!

答えて

2

あなたは正確に1「ポイント」属性を期待しているなら、あなたがちょうどその名前のためのすべての子孫を検索することができます:

ゼロがあるかどう Single()が例外をスローします
var xmlString = @"<svg width=""1200"" height=""800"" version=""1.1"" bordercolor=""#666666"" borderopacity=""1.0"" xmlns=""http://www.w3.org/2000/svg""> 
    <polyline stroke=""#004976"" fill=""transparent"" stroke-width=""5"" points=""479,91 ..."" /> 
</svg>"; 

var pointsValue = XDocument.Parse(xmlString) 
    .Descendants() 
    .Attributes("points") 
    .Single() 
    .Value; 

コレクション内の複数の要素。または、.Descendants().Attributes("points")のすべての結果を通じて.Single()foreachを削除できます。

1

svg.Descendants().First()を実行すると、文書の最初の子孫であるsvgが表示されます。

代わりにsvg.Root.Descendants().First()、またはちょうどsvg.Root.FirstNode as XElementとしてください。

string svgString = @"<svg width='1200' height='800' version='1.1' bordercolor='#666666' borderopacity='1.0' xmlns='http://www.w3.org/2000/svg'> 
    <polyline stroke='#004976' fill='transparent' stroke-width='5' points='479,91 ...' /> 
</svg>"; 
var svg = XDocument.Parse(svgString); 
XElement shape = svg?.Root?.FirstNode as XElement; 

if (shape == null) return null; 

string pointsValue = shape.Attribute("points").Value; 

var points = pointsValue.Split(' ').Select(x => x.Split(',')) 
         .Select(y => new Point(int.Parse(y[0]), int.Parse(y[1]))) 
         .ToArray(); 


Console.ReadKey(); 

ただ、これは「...」例外が発生しますSVG属性、中のbecauaseなく、かなりの仕事が....また、/自分の価値観は非常によく、小数になってしまう可能性があることに注意することに注意してくださいダブルス/浮動小数点数ではなく、int型(例えばpoints='479.994,91.2223 ....'

+0

情報ありがとうございます、私はこれを試してみましょう! 'int.Parse'問題を指摘してくれてありがとう、私はそれを完全に見落としました。 '...'はポイントのリストを切り捨てる方法です。 –

+1

はい、私は '...'について考えています。ちょうど有効な非int値があることに気付くだけですが、問題はありません。これが助けられたなら、それを正解とみなしてアップマーク/マークすることを検討してください。 –

関連する問題