Как я могу получить значение атрибута href из узла <? Xml-stylesheet>? - PullRequest
9 голосов
/ 22 января 2010

Мы получаем XML-документ от поставщика, которому необходимо выполнить XSL-преобразование с использованием их таблицы стилей, чтобы мы могли преобразовать полученный HTML-код в PDF. На фактическую таблицу стилей ссылаются в атрибуте href определения ?xml-stylesheet в документе XML. Есть ли способ, которым я могу получить этот URL с помощью C #? Я не доверяю поставщику не менять URL-адрес и, очевидно, не хочу жестко его кодировать.

Начало XML-файла с полным элементом ?xml-stylesheet выглядит следующим образом:

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

Ответы [ 6 ]

4 голосов
/ 23 января 2010

Поскольку инструкция обработки может иметь любое содержимое, формально она не имеет никаких атрибутов. Но если вы знаете, что есть «псевдо» атрибуты, как в случае инструкции обработки таблицы стилей 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.");
    }
3 голосов
/ 22 января 2010

Вы также можете использовать XPath. С учетом XmlDocument, загруженного с вашим источником:

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

Затем просто проанализируйте InnerText с помощью регулярного выражения.

3 голосов
/ 22 января 2010

Код 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.

2 голосов
/ 22 января 2010

Чтобы найти значение с помощью правильного парсера 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;
        }
    }
}
1 голос
/ 20 марта 2014
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 голосов
/ 04 января 2017

XmlProcessingInstruction stylesheet = doc.SelectSingleNode ("инструкция обработки ('xml-stylesheet')") как XmlProcessingInstruction;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...