2010-01-22 3 views
7

Chúng tôi đang nhận được một tài liệu XML từ một nhà cung cấp mà chúng tôi cần thực hiện một phép biến đổi XSL bằng cách sử dụng biểu định kiểu của chúng để chúng tôi có thể chuyển đổi HTML kết quả thành một tệp PDF. Biểu định kiểu thực tế được tham chiếu trong thuộc tính href của định nghĩa ?xml-stylesheet trong tài liệu XML. Có cách nào để tôi có thể lấy URL đó bằng C# không? Tôi không tin tưởng nhà cung cấp không thay đổi URL và rõ ràng là không muốn mã hóa nó.Làm cách nào để có được giá trị thuộc tính href trong nút <? Xml-stylesheet>?

Sự bắt đầu của tập tin XML với các yếu tố đầy đủ ?xml-stylesheet trông như thế này:

<?xml version="1.0" encoding="utf-8"?> 
<?xml-stylesheet type="text/xsl" href="http://www.fakeurl.com/StyleSheet.xsl"?> 

Trả lời

2

LINQ mã xml:

XDocument xDoc = ...; 

var cssUrlQuery = from node in xDoc.Nodes() 
     where node.NodeType == XmlNodeType.ProcessingInstruction 
     select Regex.Match(((XProcessingInstruction)node).Data, "href=\"(?<url>.*?)\"").Groups["url"].Value; 

hoặc LINQ to Objects

var cssUrls = (from XmlNode childNode in doc.ChildNodes 
        where childNode.NodeType == XmlNodeType.ProcessingInstruction && childNode.Name == "xml-stylesheet" 
        select (XmlProcessingInstruction) childNode 
        into procNode select Regex.Match(procNode.Data, "href=\"(?<url>.*?)\"").Groups["url"].Value).ToList(); 

xDoc .XPathSelectElement() sẽ không hoạt động vì nó cho một số reasone không thể cast một XElement để XProcessin gStstruction.

+0

Tôi muốn sử dụng DOM hoặc LinqToXml, nhưng tôi càng khai thác càng nhiều thì có vẻ như đây là lựa chọn duy nhất. –

+0

Vâng, tôi cũng đã đấu tranh với điều đó. Nếu có cách nào đó tôi có thể xử lý ProcessInstruction như một Element, nó sẽ đơn giản hơn. –

1

Để tìm giá trị sử dụng một phân tích cú pháp XML thích hợp, bạn có thể viết một cái gì đó như thế này:


using(var xr = XmlReader.Create(input)) 
{ 
    while(xr.Read()) 
    { 
     if(xr.NodeType == XmlNodeType.ProcessingInstruction && xr.Name == "xml-stylesheet") 
     { 
      string s = xr.Value; 
      int i = s.IndexOf("href=\"") + 6; 
      s = s.Substring(i, s.IndexOf('\"', i) - i); 
      Console.WriteLine(s); 
      break; 
     } 
    } 
} 
3

Bạn cũng có thể sử dụng XPath. Cho một XmlDocument tải với nguồn của bạn:

XmlProcessingInstruction instruction = doc.SelectSingleNode("//processing-instruction(\"xml-stylesheet\")") as XmlProcessingInstruction; 
if (instruction != null) { 
    Console.WriteLine(instruction.InnerText); 
} 

Sau đó, chỉ phân tích cú pháp InnerText với Regex.

+2

Sử dụng biểu thức XPATH này và bạn không cần phải thực hiện bất kỳ Regex: 'dịch (chuỗi con sau (xử lý-lệnh ('xml-stylesheet'), 'href ='), '"', '')' –

3

Là hướng dẫn xử lý có thể có bất kỳ nội dung nào chính thức không có bất kỳ thuộc tính nào. Nhưng nếu bạn biết có các thuộc tính "giả", như trong trường hợp lệnh xử lý xml-stylesheet, thì dĩ nhiên bạn có thể sử dụng giá trị của lệnh xử lý để xây dựng đánh dấu của một phần tử đơn lẻ và phân tích cú pháp đó với trình phân tích cú pháp XML :

XmlDocument doc = new XmlDocument(); 
    doc.Load(@"file.xml"); 
    XmlNode pi = doc.SelectSingleNode("processing-instruction('xml-stylesheet')"); 
    if (pi != null) 
    { 
     XmlElement piEl = (XmlElement)doc.ReadNode(XmlReader.Create(new StringReader("<pi " + pi.Value + "/>"))); 
     string href = piEl.GetAttribute("href"); 
     Console.WriteLine(href); 
    } 
    else 
    { 
     Console.WriteLine("No pi found."); 
    } 
1
private string _GetTemplateUrl(XDocument formXmlData) 
{ 
    var infopathInstruction = (XProcessingInstruction)formXmlData.Nodes().First(node => node.NodeType == XmlNodeType.ProcessingInstruction && ((XProcessingInstruction)node).Target == "mso-infoPathSolution"); 
    var instructionValueAsDoc = XDocument.Parse("<n " + infopathInstruction.Data + " />"); 
    return instructionValueAsDoc.Root.Attribute("href").Value; 
} 
+0

Một phải sử dụng 'xml-stylesheet' thay vì' mso-infoPathSolution', nhưng sau đó nó làm việc cho tôi. Nó lấy phần tử đầu tiên và trả về kết quả. – testing

0

XmlProcessingInstruction stylesheet = doc.SelectSingleNode ("xử lý-hướng dẫn ('xml-stylesheet')") như XmlProcessingInstruction;