2010-01-22 11 views
7

Wir erhalten ein XML-Dokument von einem Hersteller, das eine XSL-Transformation bei Verwendung ihres Stylesheets durchführen muss, damit wir das resultierende HTML in ein PDF konvertieren können. Das aktuelle Stylesheet wird in einem href-Attribut der ?xml-stylesheet-Definition im XML-Dokument referenziert. Gibt es eine Möglichkeit, dass ich diese URL mit C# rausholen kann? Ich traue dem Anbieter nicht, die URL nicht zu ändern und will sie offensichtlich nicht fest codieren.Wie kann ich den href-Attributwert aus einem <? Xml-stylesheet> -Knoten herausholen?

Der Beginn der XML-Datei mit dem vollständigen ?xml-stylesheet Elemente wie folgt aussieht:

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

Antwort

2

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; 

oder Linq zu Objekten

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() funktioniert nicht, da es für einige Reasone kein XElement in XProcessin werfen kann Anleitung.

+0

Ich würde es vorziehen, das DOM oder LinqToXml zu verwenden, aber je mehr ich grabe, desto mehr sieht es so aus, als ob dies die einzige Option wäre. –

+0

Ja, ich habe auch damit gekämpft. Wenn es eine Möglichkeit gäbe, die ProcessingInstruction wie ein Element zu behandeln, wäre es einfacher. –

1

den Wert finden einen geeigneten XML-Parser verwenden Sie so etwas schreiben könnte:


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

Sie können auch XPath verwenden. Gegeben ein XmlDocument, das mit Ihrer Quelle geladen wurde:

Dann analysieren Sie InnerText mit Regex.

+2

Mit diesem Ausdruck XPATH und Sie müssen keine Regex tun: 'translate (substring-nachher (Verarbeitungsanweisung ('xml-stylesheet'), 'href ='), '"', '')' –

3

Da eine Verarbeitungsanweisung beliebige Inhalte haben kann, hat sie formal keine Attribute. Aber wenn Sie wissen, dass es "Pseudo" -Attribute gibt, wie im Falle einer XML-Stylesheet-Verarbeitungsanweisung, können Sie natürlich den Wert der Verarbeitungsanweisung verwenden, um das Markup eines einzelnen Elements zu konstruieren und dieses mit dem XML-Parser zu analysieren :

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 muss 'xml-stylesheet' anstelle von' mso-infoPathSolution' verwenden, aber dann funktioniert es für mich. Es nimmt das erste Element und gibt das Ergebnis zurück. – testing

0

XmlProcessingInstruction Sheet = doc.SelectSingleNode ("processing-Befehl ('XML-Stylesheet')" bezeichnet) als XmlProcessingInstruction;

Verwandte Themen