c#从xsi:schemaLocation属性值获取.xsd的本地路径

war*_*cik 1 c# schema xsd xml-parsing

我正在寻找一种不使用正则表达式来提取模式的本地路径的最佳方法。

样本:

<?xml version="1.0"?>
<ord:order xmlns:ord="http://example.org/ord"
   xmlns:prod="http://example.org/prod"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://example.org/prod chapter05prod.xsd
                   http://example.org/ord chapter05ord.xsd">
<items>
    <prod:product>
        <number xsi:type="xs:short">557</number>
        <name>Short-Sleeved Linen Blouse</name>
        <size xsi:nil="true"/>
    </prod:product>
</items>
Run Code Online (Sandbox Code Playgroud)

或者

xsi:schemaLocation="http://example.org/prod \\RandomFolder\New\chapter05prod.xsd">
Run Code Online (Sandbox Code Playgroud)

或者

 xsi:schemaLocation="chapter05prod.xsd">
Run Code Online (Sandbox Code Playgroud)

我想获取 *.xsd 文件的本地路径。有没有办法使用 xml 解析器或 xmlResolver 或其他不使用正则表达式的方式来做到这一点?

编辑:我正在寻找一种最通用的方法来获取外部 .xsd 路径引用的路径。

另一个例子:

xsi:noNamespaceSchemaLocation="file://C://Documents and Settings//All Users//Application Data//My Application//MyData.xsd"
Run Code Online (Sandbox Code Playgroud)

hel*_*cha 6

您可以使用 XPath:

using System;
using System.Xml;
using System.Xml.XPath;
Run Code Online (Sandbox Code Playgroud)

由于您需要的数据位于由名称空间限定的属性内,因此您需要在执行 XPath 表达式之前注册名称空间。在您的情况下,您可以忽略命名空间并使用这样的表达式:

//@*[local-name()='schemaLocation']
Run Code Online (Sandbox Code Playgroud)

这将选择具有本地名称schemaLocation(忽略其前缀)的属性节点。

解析您的 XML 文件并获取根(文档)元素:

XmlTextReader reader = new XmlTextReader("your-file.xml");
XmlDocument doc = new XmlDocument(); 
doc.Load(reader);
reader.Close();
XmlElement root = doc.DocumentElement;
Run Code Online (Sandbox Code Playgroud)

然后使用它来选择所有名为 的属性schemaLocation。只有一个,所以你可以使用SelectSingleNode

XmlNode schemaLocationAttribute = root.SelectSingleNode("//@*[local-name()='schemaLocation']");
Run Code Online (Sandbox Code Playgroud)

上面的表达式包含属性。您可以使用schemaLocationAttribute.Value. 从那里您可以使用空格作为分隔符拆分内容:

string[] components = schemaLocationAttribute.Value.Split(null);
Run Code Online (Sandbox Code Playgroud)

您将拥有所需的文本 ( chapter05prod.xsd) components[1]

Console.WriteLine (components[1]);
Run Code Online (Sandbox Code Playgroud)

(注意:您不能总是忽略 XPath 命名空间 - 如果schemaLocation您的文件中存在具有不同前缀或没有前缀的其他属性,则该 XPath 表达式也会选择它们,并且此解决方案将失败。)