2010-02-26 1 views
1

Я пытаюсь идентифицировать все узлы в дереве, которые приводят к определенному узлу.альтернатива предку или себе (или выбрать все узлы в дереве с определенным дочерним узлом)

Я пытаюсь выполнить это через MSSQL XML (2005) или Microsoft.XMLDOM в ASP classic.

Я знаю логику с XPATH, но SQL Server не поддерживает ancestor-or-self ось и XMLDOM кажется задыхаться на :: нотации ..

, который работает XPath, когда я проверить его в XPATH тестеров

//static[@id=6]/ancestor-or-self::static 

мой XML (генерируется рекурсивно в SQL Server) выглядит

<root> 
    <static id="1" title="some title 1" /> 
    <static id="2" title="some title 2"> 
    <children> 
     <static id="3" title="some title 3" /> 
     <static id="4" title="some title 4"> 
      <children> 
      <static id="5" title="some title 5" /> 
      <static id="6" title="some title 6" /> 
      </children> 
     </static> 
    </children> 
    </static> 
    <static id="7" title="some title 7" /> 
</root> 

XPATH должны выбрать узлы с идентификатором (2, 4,6) в любом порядке, поэтому я могу добавить атрибут ко всем из них.

Это для системы меню, где я знаю только выбранный лист и должен отмечать как hilited все узлы, ведущие к это ..

Я был бы признателен за любую помощь в преодолении либо XMLDOM удушья (xml.documentElement.selectNodes("//static[@id=6]/ancestor-or-self::static") работает производит следующее сообщение об ошибке: Expected token 'eof' found ':'. //static[@id=6]/ancestor-or-self-->:<--:static)

или с поиском альтернативного решения. Возможно, найти все узлы, которые содержат определенный узел (с id = 6) на любой глубине.

+0

альтернативное решение с точки зрения чего? новый парсер, другой xpath или другой язык программирования? –

+0

@Jimmy, любая альтернатива, кроме изменения технологий, поскольку проект уже выполняется. –

+1

Какую версию XMLDocument вы используете в классической части ASP реализации? –

ответ

1

Запуск на W2K3 с использованием IIS6 i протестировал версию MSXML2.XMLDomDocument.4.0.

Dim XMLDom ''# As MSXML2.DOMDocument40 

Set XMLDom = CreateObject("MSXML2.DOMDocument.4.0") 
Call XMLDom.setProperty("SelectionLanguage", "XPath") 

Call XMLDom.loadXML({document as described above - mistakes in original xml doc) 
) 


Dim originalQuery ''# As String 
originalQuery = "//static[@id=6]/ancestor-or-self::static" 

Dim replacementQuery ''# As String 
replacementQuery = "//static[descendant::static[@id=6] or @id=6]" 


Dim XmlElemList ''# As MSXML2.IXMLDOMNodeList 
Set XmlElemList = XMLDom.documentElement.selectNodes(originalQuery) 

Dim XmlElemList2 ''# As MSXML2.IXMLDOMNodeList 
Set XmlElemList2 = XMLDom.documentElement.selectNodes(replacementQuery) 

Dim XmlElem ''# As MSXML2.IXMLDOMElement 
Call Response.Write("Using original query : '" & originalQuery & "' (" & XmlElemList.Length & ")<br>") 
For Each XmlElem In XmlElemList 
    Call Response.Write("XmlEntry : " & XmlElem.getAttribute("id") & "<br>") 
    Call Response.Write("****<br>") 
Next 

Call Response.Write("Using replacement query : '" & replacementQuery & "' (" & XmlElemList2.Length & ")<br>") 
For Each XmlElem In XmlElemList2 
    Call Response.Write("XmlEntry : " & XmlElem.getAttribute("id") & "<br>") 
    Call Response.Write("****<br>") 
Next 
+0

Да, это, кажется, проблема .. сменив ее на версию 4 или 5 сделал трюк ... Большое спасибо :) * Я использовал «Microsoft.XMLDOM», который загрузил версию 2: o * –

4

Это «ответы на вопросы».

Прежде всего, ваша основная проблема заключается в том, что «Microsoft.XMLDOM» обычно загружает версию 3.0 (MSXML3.dll). MSXML3 поддерживает полный язык XPATH 1.0, но не по умолчанию. Следовать должны быть достаточно, чтобы исправить: -

dom.SetProperty "SelectionLanguage", "XPath" 

ответ Марвина включает эту строку при использовании Msxml4 но это не является необходимым, так как XPath является языком выбора по умолчанию 4 и выше.

Однако я использую слово должно выше. Я часто сталкивался с серверами, которые были скомпрометированы сторонним приложением, которое также включает дистрибутив MSXML2, но неправильно устанавливает его. Они вызывают «Microsoft.XMLDOM» и не относящийся к версии «MSXML2.DOMDocument», чтобы возвращать реализацию MSXML2.dll вместо реализаций MSXML3.

Я поэтому рекомендую, чтобы лучший ProgID для использования был «MSXML2.DOMDocument.3.0», так как вы точно знаете, что именно получаете. Кроме того, MSXML3.dll гарантированно будет установлен на все поддерживаемые в настоящее время операционные системы Windows из коробки. Также MSXML3 оставался совместимым с ошибками в имплантации MSXML2, когда DOM Document вызывается с использованием более старого progID. Использование специфичного для версии ProgID приводит к тому, что MSXML3 более строго соответствует стандартам XML.

+0

+1, Отличная информация там, Энтони, спасибо за продолжение .. (* должен быть включен и не скомпрометирован?) –

+0

По умолчанию злые! Кажется, они со временем меняются. Угадайте, что вопрос о том, какой язык выбора он использует при достижении XML 10.0;) –

+0

@Marvin: По умолчанию отличные они, конечно, не злые, без по умолчанию наш код будет намного сложнее писать. Например, ваши XPaths в вашем ежедневном коде, набитый «child ::», чтобы не полагаться на то, что «child ::» - это ось __default__, используемая XPath? Я излагаю эти «аккуратные» ответы, чтобы убедиться, что нет никаких ошибочных представлений о том, что происходит на самом деле. Это может быть construde из вашего кода, который требует XPath, это не так. Однако я бы согласился, что есть определенный комфорт, который приходит от того, чтобы быть явным в этом отношении. – AnthonyWJones