Я ищу лучший способ exctract локального пути схемы без использования регулярного выражения.
Образец:
<?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>
или
xsi:schemaLocation="http://example.org/prod \\RandomFolder\New\chapter05prod.xsd">
или
xsi:schemaLocation="chapter05prod.xsd">
Я хотел бы получить локальный путь для файла *.xsd. Есть ли способ сделать это с помощью анализатора xml или xmlResolver или каким-либо другим способом, который не использует регулярное выражение?
Изменение: Я ищу наиболее общий подход, чтобы получить путь для внешних ссылок пути.xsd.
Другой пример:
xsi:noNamespaceSchemaLocation="file://C://Documents and Settings//All Users//Application Data//My Application//MyData.xsd"
Вы можете использовать XPath:
using System;
using System.Xml;
using System.Xml.XPath;
Поскольку требуемые данные находятся внутри атрибута, который определяется пространством имен, вам нужно будет зарегистрировать пространство имен перед выполнением выражения XPath. В вашем случае вы можете игнорировать пространство имен и использовать выражение, подобное этому:
//@*[local-name()='schemaLocation']
который выберет узел атрибута, который имеет локальное имя schemaLocation
(игнорируя его префикс).
Разберите XML файл и получите элемент root (document):
XmlTextReader reader = new XmlTextReader("your-file.xml");
XmlDocument doc = new XmlDocument();
doc.Load(reader);
reader.Close();
XmlElement root = doc.DocumentElement;
Затем используйте его для выбора всех атрибутов с именем schemaLocation
. Существует только один, поэтому вы можете использовать SelectSingleNode
:
XmlNode schemaLocationAttribute = root.SelectSingleNode("//@*[local-name()='schemaLocation']");
Вышеприведенное выражение содержит атрибут. Вы можете получить его содержимое строки, используя schemaLocationAttribute.Value
. Оттуда вы можете разделить содержимое, используя пробел, в качестве разделителя:
string[] components = schemaLocationAttribute.Value.Split(null);
И вы получите текст, который вы хотите (chapter05prod.xsd
) в components[1]
:
Console.WriteLine (components[1]);
(Примечание: вы не можете всегда игнорировать пространства имен XPath - если в вашем файле были другие атрибуты с именем schemaLocation
с другим префиксом или без префикса, они также были бы выбраны этим выражением XPath, и это решение не получится.)
schemaLocation
илиnoNamespaceSchemaLocation
поскольку действительная схема URI требует их экранирования (до%20
). Таким образом, URL-адрес, такой как:file:///c:/My Directory/file.xsd
, будет включен какfile:///c:/My%20Directory/file.xsd
. Пространства также важны вschemaLocation
так как они используются для отделения каждой схемы от ее местоположения, а также пар схема / местоположение.