2015-01-02 4 views
1

우리는이 XML 파일을하고 난XPath는

<bookstore> 
<book author="Tommy"> 
    <title>Emma</title> 
</book> 
</bookstore> 

내가 알고 타이틀을 얻을 수있는 변수로 속성 저자을 사용하려면 우리는 또한이 예제가 있다면 나는이

string au = "Tommy"; 
string query = String.Format("//bookstore/book[@author={0}]/title", au); 

를 작성해야합니다 나는

<bk:bookstore xmlns:bk="http://www.example.com/"> 
    <book author="Tommy"> 
    <title>Emma</title> 
    </book> 
</bk:bookstore> 

내가 일을 알고 타이틀을 얻으려면 나는이

XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable); 
nsmgr.AddNamespace("bk", "http://www.test.com/"); 
XmlNodeList elements0 = xml.SelectNodes("//bk:bookstore/book/title", nsmgr); 

를 작성해야하지만 내가 두 번째 예제를 가지고 있고 또한 변수로 속성 저자을 사용하려면 어떻게 해야할지하지 않습니다에. 나는

XmlNodeList elements0 = xml.SelectNodes("//bk:bookstore/book[@author={1}]/title", nsmgr, au); 

string au = "Tommy"; 
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable); 
nsmgr.AddNamespace("bk", "http://www.test.com/"); 
XmlNodeList elements0 = xml.SelectNodes("//bk:bookstore/book[@author={0}]/title", au, nsmgr); 

또는이

XmlNodeList elements0 = xml.SelectNodes("//bk:bookstore/book[@author={0}]/title", nsmgr, au); 

또는이를 시도했지만 작동하지 않습니다. 아무도 도와 줄 수 있습니까?

+1

XML의 네임 스페이스는 'http : // www.example.com /'이지만 네임 스페이스 관리자에서'http : // www.test.com/ '를 사용하고 있습니다. – JLRishe

답변

1

당신은 물건을 혼합하고 있습니다.

먼저 경로를 만드십시오. 그런 다음 사용하십시오. 네임 스페이스 관리자는 두 번째 단계에서만 중요합니다.

string au = "Tommy"; 
string path = String.Format("//bk:bookstore/book[@author = '{0}']/title", au); 

XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable); 
nsmgr.AddNamespace("bk", "http://www.test.com/"); 

XmlNodeList elements0 = xml.SelectNodes(path, nsmgr); 

경로의 작은 따옴표에 유의하십시오.


또한주의 입력 문자열 (au)에 작은 따옴표가이 것이다 휴식이. 이것은 최악의 경우 XPath 주입을위한 최상의 경우와 공격 벡터에서 임의의 런타임 오류의 원인이 될 수 있습니다. 즉, 이 해당 상황을 처리해야 함을 의미합니다. 이 문제를 해결하기 위해

옵션은 다음과 같습니다

  1. 명시 적으로 입력에 작은 따옴표를 금지하고 경로를 구축 할 때 추가로 au.Replace("'", "")를 사용합니다. 이것은 아마 사람 이름에 적합하지 않습니다.
  2. 작은 따옴표를 허용하는보다 복잡한 경로를 작성하십시오. XPath에는 문자열에 대한 이스케이프 처리 메커니즘이 없으므로 사소하지 않습니다. 옵션 2의

Use a more advanced way of defining an XPath query., 저자 "O'Reilly" 가정, 경로는 다음과 같이해야합니다 :

//bk:bookstore/book[@author = concat('O', "'", 'Reilly')]/title 

을 표현 concat('O', "'", 'Reilly')이 XPath는 엔진에서 문자열 "O'Reilly"을 생산하기 때문이다. 이 방법으로 concat()을 사용하면 따옴표를 XPath 문자열에 포함 할 수있는 유일한 방법입니다.

이 기능은 식을 생성합니다

public static string XPathEscape(string input) 
{ 
    if (String.IsNullOrEmpty(input)) return "''"; 

    if (input.Contains("'")) 
    { 
     string[] parts = input.Split("'".ToCharArray()); 
     return String.Format("concat('{0}')", String.Join(@"', ""'"", '", parts)); 
    } 
    else 
    { 
     return String.Format("'{0}'", input); 
    } 
} 

사용은 다음과 같이 : 경로에는 작은 따옴표이 시간이 없음을

string au = "O'Reilly"; 
string path = String.Format("//bk:bookstore/book[@author = {0}]/title", XPathEscape(au)); 

참고.