如何从<! - ?xml-stylesheet - >节点中获取href属性值?

时间:2010-01-22 19:00:25

标签: c# xml xslt

我们从供应商处获取XML文档,我们需要使用它们的样式表执行XSL转换,以便我们可以将生成的HTML转换为PDF。实际样式表在XML文档中href定义的?xml-stylesheet属性中引用。有什么方法可以使用C#获取该URL吗?我不相信供应商不会更改URL,显然也不想对其进行硬编码。

带有完整?xml-stylesheet元素的XML文件的开头如下所示:

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

6 个答案:

答案 0 :(得分:4)

由于处理指令可以包含任何内容,因此它正式没有任何属性。但是如果你知道有“伪”属性,比如xml-stylesheet处理指令的情况,那么你当然可以使用处理指令的值来构造单个元素的标记并用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 :(得分:3)

Linq to xml code:

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 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()将无效,因为某些reasone无法将XElement强制转换为XProcessingInstruction。

答案 2 :(得分:3)

您也可以使用XPath。给定一个XmlDocument加载了您的源:

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

然后用Regex解析InnerText。

答案 3 :(得分:2)

要使用正确的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;
        }
    }
}

答案 4 :(得分: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;
}

答案 5 :(得分:0)

XmlProcessingInstruction stylesheet = doc.SelectSingleNode(&#34; processing-instruction(&#39; xml-stylesheet&#39;)&#34;)作为XmlProcessingInstruction;