【问题标题】:C# SelectSingleNode returns nullC# SelectSingleNode 返回 null
【发布时间】:2023-03-07 13:47:01
【问题描述】:

我正在尝试从 .svg 文件中获取一个节点,该文件包含一些 xml 格式的信息。 这是我的代码:

                XmlDocument document = new XmlDocument();
                document.Load(openFileDialog.FileName);
                XmlNamespaceManager xmlnsManager = new XmlNamespaceManager(document.NameTable);
                xmlnsManager.AddNamespace("inkscape", "http://www.inkscape.org/namespaces/inkscape");
                xmlnsManager.AddNamespace("sodipodi", "http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd");
                xmlnsManager.AddNamespace("xlink", "http://www.w3.org/1999/xlink");
                xmlnsManager.AddNamespace("svg", "http://www.w3.org/2000/svg");

                XmlNode node = document.DocumentElement.SelectSingleNode("sodipodi:namedview/g/image]", xmlnsManager);

根据微软的文档,我也试过了:

descendant::sodipodi:namedview[sodipodi:g/sodipodi:image]

我还尝试了在 g/ 和 image 之前使用和不使用“sodipodo”的两个版本。 如果我只写“sodipodi:namedview”,它会找到节点并返回它,但我更愿意直接找到我需要的那个,而不是遍历它。 这是 xml 文件的简短版本:

<svg
   width="210mm"
   height="297mm"
   viewBox="0 0 210 297"
   version="1.1"
   id="svg5"
   inkscape:version="1.1 (c68e22c387, 2021-05-23)"
   sodipodi:docname="Zeichnung.svg"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <sodipodi:namedview
     id="namedview7"
     pagecolor="#505050"
     bordercolor="#eeeeee"
     borderopacity="1"
     inkscape:pageshadow="0"
     inkscape:pageopacity="0"
     inkscape:pagecheckerboard="0"
     inkscape:document-units="mm"
     showgrid="false"
     inkscape:zoom="0.46324355"
     inkscape:cx="616.30648"
     inkscape:cy="601.19564"
     inkscape:window-width="1366"
     inkscape:window-height="705"
     inkscape:window-x="1912"
     inkscape:window-y="101"
     inkscape:window-maximized="1"
     inkscape:current-layer="layer1" />
  <defs
     id="defs2">
    <rect
       x="69.078134"
       y="554.78377"
       width="613.06844"
       height="252.56693"
       id="rect1536" />
  </defs>
  <g
     inkscape:label="Ebene 1"
     inkscape:groupmode="layer"
     id="layer1">
    <image
       width="209.62195"
       height="110.57917"
       preserveAspectRatio="none"
       style="image-rendering:optimizeSpeed"
       xlink:href="Really long base64 string"
       id="image47"
       x="-2.8600111"
       y="-0.1732364" />
  </g>
</svg>

【问题讨论】:

  • 据我所知,该图像不包含在 namedview 元素中,即没有子元素的元素。在 Visual Studio 中,输入您的简短 xml 版本,然后将 XPath 复制到图像,我得到/svg:svg/svg:g/svg:image。我错过了什么吗?
  • @cph 不,你是对的,这解决了它,我只是瞎了,不知何故长达数小时

标签: c# xml wpf file svg


【解决方案1】:
  1. 您的 XML 路径错误:g 不是 sodipodi:namedview 的子级。他们是兄弟姐妹。
  2. XPath 格式错误:删除结尾的 ']' 字符
  3. 您已通过在svg 元素上声明xmlns="http://www.w3.org/2000/svg"(无别名/前缀)定义了默认命名空间,但您没有使用默认命名空间限定声明节点的子类型。根据 XML 命名空间规则,默认命名空间“继承”到定义命名空间的父元素的所有子元素(在这种情况下为 svg)。元素的默认命名空间定义了一个隐式前缀,隐式应用于所有子元素。

为了能够使用默认命名空间限定您的元素,您首先必须注册它

xmlnsManager.AddNamespace("default", "http://www.w3.org/2000/svg");

其中default 是映射默认命名空间的随机别名。

注册默认命名空间后,修改 XPath 以使用别名限定 svg 的子类型。

固定的 XPath 如下所示:

XmlNode node = document.DocumentElement.SelectSingleNode("default:g/default:image", xmlnsManager);

或者从svg 元素中删除默认命名空间声明xmlns="http://www.w3.org/2000/svg"

【讨论】:

    【解决方案2】:

    试试 xmllinq:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication2
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
                XNamespace ns = doc.Root.GetDefaultNamespace();
                XNamespace nsXlink = doc.Root.GetNamespaceOfPrefix("xlink");
                XElement image = doc.Descendants(ns + "image").FirstOrDefault();
                double width = (double)image.Attribute("width");
                double height = (double)image.Attribute("height");
                string ratio = (string)image.Attribute("preserveAspectRatio");
                string style = (string)image.Attribute("style");
                string href = (string)image.Attribute(nsXlink + "href");
                string id = (string)image.Attribute("id");
                double x = (double)image.Attribute("x");
                double y = (double)image.Attribute("y");
    
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-09
      • 2023-03-07
      相关资源
      最近更新 更多