Мы получаем XML-документ от поставщика, которого мы должны выполнить, XSL преобразовывают при использовании их таблицы стилей так, чтобы мы могли преобразовать получающийся HTML в PDF. На фактическую таблицу стилей ссылаются в href
атрибут ?xml-stylesheet
определение в XML-документе. Есть ли какой-либо способ, которым я могу получить тот URL с помощью C#? Я не доверяю поставщику для не изменения URL и очевидно не хочу к hardcode его.
Запуск XML-файла с полным ?xml-stylesheet
элемент похож на это:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="http://www.fakeurl.com/StyleSheet.xsl"?>
LINQ до 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.xPathELEctelection () не будет работать, поскольку для некоторого значения не может отбросить xElement к XProcessingIntruction.
В качестве инструкции по обработке может иметь любое содержимое, которое он формально не имеет никаких атрибутов. Но если вы знаете, что есть атрибуты «псевдо», как в случае в случае инструкции обработки 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.");
}
Вы также можете использовать XPath. Учитывая XMLDocument, загруженный вашим источником:
XmlProcessingInstruction instruction = doc.SelectSingleNode("//processing-instruction(\"xml-stylesheet\")") as XmlProcessingInstruction;
if (instruction != null) {
Console.WriteLine(instruction.InnerText);
}
, а затем просто анализировать Innertext с Regex.
Чтобы найти значение, используя правильный анализатор 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;
}
}
}