2010-01-22 64 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;

相关问题