Поиск нескольких элементов с XPATH с неизвестным префиксом пространства имен EXCEL VBA - PullRequest
0 голосов
/ 17 февраля 2020

Я загружаю разные XML файлы, которые содержат разные xmlns namespaces having specific prefixes например x,i,s,dt,xx etc., которые меняются с разными XML файлами. Я ищу несколько узлов Element, например, AttributeType, которым может предшествовать префикс пространства имен.

Мой вопрос: как выбрать несколько узлов using VBA, не зная префикса пространства имен xmlns (например, будет ли это s или xx), который может быть добавлен к узлу в качестве префикса?

Пример:

<xml 
xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" 
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" 
xmlns:rs="urn:schemas-microsoft-com:rowset" 
xmlns:z="#RowsetSchema">
    <s:Schema id="RowsetSchema">
        <s:ElementType name="row" content="eltOnly" rs:updatable="true">
            <s:AttributeType name="F1" rs:number="1" rs:nullable="true" rs:maydefer="true" rs:writeunknown="true" rs:basetable="abc$" rs:basecolumn="F1">
                <s:datatype dt:type="string" dt:maxLength="255"/>
            </s:AttributeType>
            <s:AttributeType name="F2" rs:number="1" rs:nullable="true" rs:maydefer="true" rs:writeunknown="true" rs:basetable="abc$" rs:basecolumn="F2">
                <s:datatype dt:type="string" dt:maxLength="255"/>
            </s:AttributeType>
....
        </s:AttributeType>
        <s:extends type="rs:rowbase"/>
    </s:ElementType>
</s:Schema>
<rs:data>
    <z:row F2="F2" F4="F4" F5="F5"/>
    <z:row F1="1.3" F2="2.3" F5="1.1"/>
    <z:row F1="3.4" F3="2.8" F4="5.3"/>
....
</xml>

Другой пример:

<xml 
xmlns:xx="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" 
xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" 
xmlns:rs="urn:schemas-microsoft-com:rowset" 
xmlns:z="#RowsetSchema">
    <xx:Schema id="RowsetSchema">
        <xx:ElementType name="row" content="eltOnly" rs:updatable="true">
            <xx:AttributeType name="F1" rs:number="1" rs:nullable="true" rs:maydefer="true" rs:writeunknown="true" rs:basetable="abc$" rs:basecolumn="F1">
                <xx:datatype dt:type="string" dt:maxLength="255"/>
            </xx:AttributeType>
            <xx:AttributeType name="F2" rs:number="1" rs:nullable="true" rs:maydefer="true" rs:writeunknown="true" rs:basetable="abc$" rs:basecolumn="F2">
                <xx:datatype dt:type="string" dt:maxLength="255"/>
            </xx:AttributeType>
....
        </s:AttributeType>
        <s:extends type="rs:rowbase"/>
    </s:ElementType>
</s:Schema>
<rs:data>
    <z:row F2="F2" F4="F4" F5="F5"/>
    <z:row F1="1.3" F2="2.3" F5="1.1"/>
    <z:row F1="3.4" F3="2.8" F4="5.3"/>
....
</xml>

Вот пример кода VBA:

Sub TestMe()

Dim XML As Object
Dim sFilePath As String, sXML As String, K As Variant, FirstDataRow As Object
Dim oRS As Object, Attr_XPath As String, FirstDataRow_XPath As String
Dim Attrs As Object, Attr As Object, I As Long, J As Long

sFilePath = "C:\Test_ADO.xml"
Set XML = CreateObject("Microsoft.XMLDOM")
XML.Load (sFilePath)

Attr_XPath = "//@*[name()='AttributeType']"
FirstDataRow_XPath = "//@*[name()='row']"

Set Attrs = XML.SelectNodes(Attr_XPath)
Set FirstDataRow = XML.SelectSingleNode(FirstDataRow_XPath)

Stop
For Each K In FirstDataRow.Attributes
    For Each Attr In Attrs
   '....
    Next Attr
Next K

....
End Sub

1 Ответ

0 голосов
/ 18 февраля 2020

Пространство имен agnosti c Способ построения выражения XPath прост, но делает выражения намного длиннее. Для каждого элемента вы предоставляете следующее подвыражение:

/*[local-name()='AttributeType']

Функция name () возвращает префикс и локальное имя элемента, например, «s: AttributeType», а local-name () возвращает только его локальную часть.

...