Запрос XmlDocument без получения проблемы «Префикс пространства имен не определен» - PullRequest
11 голосов
/ 24 марта 2010

У меня есть документ Xml, который определяет и ссылается на некоторые пространства имен. Я загружаю его в объект XmlDocument и, насколько мне известно, создаю объект XmlNamespaceManager, с помощью которого можно запросить Xpath. Проблема в том, что я получаю исключения XPath, что пространство имен «my» не определено. Как получить диспетчер пространства имен, чтобы увидеть, что пространства имен, на которые я ссылаюсь, уже определены. Или, скорее, как я могу получить определения пространства имен из документа в диспетчер пространства имен.

Кроме того, мне кажется странным, что вы должны предоставить менеджера пространства имен для документа, который вы создаете из документов, которые можно в первую очередь назвать. Даже если вам нужно жестко закодировать пространства имен вручную, почему вы не можете добавить их непосредственно в документ. Почему вы всегда должны передавать этот менеджер пространства имен с каждым запросом? Чего не может знать XmlDocument?

Код:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(programFiles + @"Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\HfscBookingWorkflow\template.xml");
XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable);

XmlNode referenceNode = xmlDoc.SelectSingleNode("/my:myFields/my:ReferenceNumber", ns);
referenceNode.InnerXml = this.bookingData.ReferenceNumber;

XmlNode titleNode = xmlDoc.SelectSingleNode("/my:myFields/my:Title", ns);
titleNode.InnerXml = this.bookingData.FamilyName;

Xml:

  <?xml version="1.0" encoding="UTF-8" ?> 
  <?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:Inspection:-myXSD-2010-01-15T18-21-55" solutionVersion="1.0.0.104" productVersion="12.0.0" PIVersion="1.0.0.0" ?> 
  <?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?> 
  <my:myFields xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003">
  <my:DateRequested xsi:nil="true" /> 
  <my:DateVisited xsi:nil="true" /> 
  <my:ReferenceNumber /> 
  <my:FireCall>false</my:FireCall> 

Обновление:

ns.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
ns.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
ns.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003");
ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55");

Это делает работу, но это значит, что мне нужно жестко написать код для этой конкретной XML-схемы. Эта схема представляет шаблон формы Infopath. В частности, URL-адрес моего пространства имен будет отличаться для каждого шаблона формы, поэтому я действительно не хочу жестко кодировать это. Было бы неплохо найти чистый способ получить это пространство имен из xml, не прибегая к RegEx.

Я надеялся, что XmlNamespaceManager просто выберет определения пространства имен из NameTable. Я имею в виду их в XML, но я все еще должен определить их.

Ответы [ 4 ]

5 голосов
/ 25 марта 2010
ns.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
ns.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
ns.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003");
ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55");

Это делает работу, но это значит, что мне нужно жестко написать код для этой конкретной XML-схемы. Эта схема представляет шаблон формы Infopath. В частности, URL-адрес моего пространства имен будет отличаться для каждого шаблона формы, поэтому я действительно не хочу жестко кодировать это. Было бы неплохо найти чистый способ получить это пространство имен из XML, не прибегая к Regex.

Я надеялся, что XmlNamespaceManager просто выберет определения пространства имен из NameTable. Я имею в виду их в XML, но я все еще должен определить их.

3 голосов
/ 24 марта 2010

Вот ответ на вопрос «Что не может знать XmlDocument?» вопрос.

NameTable - это просто оптимизация для хранения имен. На самом деле это не имеет ничего общего с пространствами имен.

И даже если XmlNamespaceManager может вывести все пространства имен и префиксы из документа XML, что не поможет в общем случае из-за природы пространств имен XML, например, что бы XmlNamespaceManager отображал префикс «мой» в этом случае:

<root>
    <foo xmlns:my="blah"/>
    <foo xmlns:my="balh-blah-blah"/>
</root>
1 голос
/ 24 марта 2010

Вы определили "мой" в менеджере пространства имен?

ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55");

Или лучше - выберите то, что вряд ли будет конфликтовать. Тем не менее, кажется странным, что он не взял его из таблицы имен.

0 голосов
/ 31 июля 2015

Для меня с InfoPath 2007 это решило проблему

static public XmlNamespaceManager GetNameSpaceManager(this XmlDocument document)
{
    XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(document.NameTable);

    xmlNamespaceManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    xmlNamespaceManager.AddNamespace("dfs", "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution");
    xmlNamespaceManager.AddNamespace("d", "http://schemas.microsoft.com/office/infopath/2003/ado/dataFields");
    xmlNamespaceManager.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-03-29T06:28:28");
    xmlNamespaceManager.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003");

    return xmlNamespaceManager;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...