2017-02-14 5 views
1

Xamarin.Forms에서 SVG 파일을 사용하고 있습니다. 이 파일은 매우 단순하며이 모양이 대개 polyline 인 단일 모양을 포함합니다. 그러나 몇 가지 다른 포인트 기반 모양 중 하나가 될 수있는 경우가 있습니다. 이러한 파일을 구문 분석 할 때 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> 

그래서이 가장 일반적인 경우에 나는 polylinepoints 속성의 값을 얻기 위해 노력하고 있어요. 나는 이것이 간단한 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

: 제로가 있다면 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(); 

그냥 참고의 becauase이하지 않습니다 잘 작동은 "..."예외가 발생합니다 SVG 속성에 .... 또한 당신의 가치가 매우 잘되는 소수를 끝낼 수 있습니다/복식/수레,하지의 int (예를 들어, 정확히 1 속성을 다음 방금 그 이름에 대한 모든 자손을 검색 할 수 있습니다 "지적"기대하는 경우 points='479.994,91.2223 ....'

+0

정보 주셔서 감사합니다. 또한'int.Parse' 문제를 지적 해 주셔서 감사 드리며, 나는 그것을 간과했습니다. '...'는 포인트 목록을 자르는 나의 방법입니다. –

+1

그래, 나는'...'에 대해 알아 냈다. 단지 유효한 non-int 값이 있다는 것을 깨닫는다. 그러나 문제는 없다. 이것이 도움이된다면, 올바른 대답으로 upvoting/marking을 고려하십시오. –