【问题标题】:How can I get the href attribute value out of an <?xml-stylesheet> node?如何从 <?xml-stylesheet> 节点中获取 href 属性值?
【发布时间】:2010-01-22 19:00:24
【问题描述】:

我们从供应商处获得一个 XML 文档,我们需要使用他们的样式表执行 XSL 转换,以便我们可以将生成的 HTML 转换为 PDF。实际样式表在 XML 文档中 ?xml-stylesheet 定义的 href 属性中引用。有什么方法可以使用 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"?>

【问题讨论】:

    标签: c# xml xslt


    【解决方案1】:

    作为一个处理指令可以有任何内容,它形式上没有任何属性。但是,如果您知道存在“伪”属性,例如在 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.");
        }
    

    【讨论】:

    • 谢谢。花了很长时间才弄清楚这些被称为“处理指令”,而 LINQ 对我来说仍然没有任何意义!
    【解决方案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() 将不起作用,因为它由于某种原因无法将 XElement 强制转换为 XProcessingInstruction。

    【讨论】:

    • 我更喜欢使用 DOM 或 LinqToXml,但我挖掘得越多,看起来这可能是唯一的选择。
    • 是的,我也一直在为此苦苦挣扎。如果有某种方法我可以将 ProcessingInstruction 视为一个元素,那就更简单了。
    【解决方案3】:

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

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

    然后只需使用 Regex 解析 InnerText。

    【讨论】:

    • 使用这个 XPATH 表达式,你不需要做任何正则表达式:translate(substring-after(processing-instruction('xml-stylesheet'),'href='),'&amp;quot;','')
    【解决方案4】:

    要使用适当的 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;
            }
        }
    }
    

    【讨论】:

    • 使用 XmlReader 方法时,请注意,如果找到起始元素节点,则像 IsStartElement 这样的方法调用将导致阅读器跳过处理指令。在解析元素节点之前,我使用了一个单独的读取循环来解析处理指令。
    【解决方案5】:
    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;
    }
    

    【讨论】:

    • 必须使用xml-stylesheet 而不是mso-infoPathSolution,但它对我有用。它接受第一个元素并返回结果。
    【解决方案6】:

    XmlProcessingInstruction stylesheet = doc.SelectSingleNode("processing-instruction('xml-stylesheet')") as XmlProcessingInstruction;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多