2010-01-22 121 views
7

我們從供應商那裏獲得一個XML文檔,我們需要使用它們的樣式表執行XSL轉換,以便我們可以將生成的HTML轉換爲PDF。實際樣式表在XML文檔中的?xml-stylesheet定義的href屬性中引用。有沒有什麼方法可以使用C#獲取該URL?我不相信供應商不更改網址,顯然不想對其進行硬編碼。如何從<?xml-stylesheet>節點獲取href屬性值?

與全?xml-stylesheet元素的XML文件的開頭是這樣的:

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

回答

2

的LINQ to 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; 

或LINQ對象

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()將不起作用,因爲它對於某些reasone無法將XElement轉換爲XProcessin gInstruction。

+0

我寧願使用DOM或LinqToXml,但越挖越看起來像這可能是唯一的選擇。 – 2010-01-22 19:23:48

+0

是的,我也一直在努力。如果有某種方式,我可以像處理元素一樣處理ProcessingInstruction,它會更簡單。 – 2010-01-22 20:24:46

1

要找到使用適當的XML解析器你可以寫這樣的值:


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

您也可以使用XPath。給定一個XmlDocument加載你的源代碼:

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

然後只用正則表達式分析InnerText。

+2

使用這個XPATH表達式,你不需要做任何正則表達式:'translate(substring-after(processing-instruction('xml-stylesheet'),'href ='),'"','')' – 2010-01-23 03:33:52

3

作爲處理指令可以有任何內容,它正式沒有任何屬性。但是如果您知道存在「僞」屬性(如xml樣式表處理指令的情況),那麼您當然可以使用處理指令的值來構建單個元素的標記並使用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

One必須使用'xml-stylesheet'而不是'mso-infoPathSolution',但它對我來說很有用。它採用第一個元素並返回結果。 – testing 2016-12-01 13:18:04

0

XmlProcessingInstruction樣式= doc.SelectSingleNode( 「處理指令( 'xml樣式表')」)作爲XmlProcessingInstruction;