Получение элемента из другого элемента с пространством имен, отличным от корневого - PullRequest
0 голосов
/ 30 апреля 2011

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

Например, я пытаюсь получить InternalSystemId из следующего XML, но традиционный XML не будет работать

XPATH Я пытаюсь использовать

/SomeMessage[1]
   /MessageDetails[1]
      /PAYLOAD[1]
         /Call-Name[1]
            /Body[1]
               /ActionToTake[1]
                  /Fields[1]
                     /InternalSystemId[1]

XML у меня есть

<?xml version="1.0" encoding="UTF-8"?>
<SomeMessage>
    <MessageDetails>
        <FROM/>
        <TO/>
        <PAYLOAD>
            <Call-Name 
            xmlns:ns0="http://www.mysite.com/interface/genericnamespace"
            xmlns="http://www.mysite.com/interface/genericnamespace">
                <Header xmlns="">
                    <Transaction>
                        <Mandatory>
                            <TransactionId>111111</TransactionId>
                        </Mandatory>
                        <System-Use-Only>
                            <Name>Receiver</Name>
                            <Someone>Customer</Someone>
                            <Something>OUT</Something>
                        </System-Use-Only>
                    </Transaction>
                </Header>
                <Body xmlns="">
                    <ActionToTake>
                        <TransactionName>ActionToTake</TransactionName>
                        <Fields>
                            <InterfaceId>w00tie</InterfaceId>
                            <CustomerSystemId>555555</CustomerSystemId>
                            <InternalSystemId>4444444</InternalSystemId>
                            <SubmittedDate
                            >2011-04-14T12:00:00-00:00</SubmittedDate>
                            <EventType>A type</EventType>
                        </Fields>
                    </ActionToTake>
                </Body>
            </Call-Name>
        </PAYLOAD>
    </MessageDetails>
</SomeMessage>

1 Ответ

2 голосов
/ 30 апреля 2011

Элемент Call-Name находится в пространстве имен с URI, равным "http://www.mysite.com/interface/genericnamespace".. Поэтому вам необходимо либо

  1. выбрать его по имени, используя это пространство имен, либо

  2. для доступа к нему используется метод, независимый от пространства имен.

Тот факт, что элемент находится в другом пространстве имен, чем «корень» (элемент), не является прямымрелевантный.

Чтобы сделать # 1, вы должны объявить префикс для пространства имен в вашей среде выполнения XPath, например, в таблице стилей XSLT вы можете поместить xmnls:mysite="http://www.mysite.com/interface/genericnamespace". Затем вы должны выбрать элемент, используя этот префикс иимя элемента, например

/SomeMessage[1]/MessageDetails[1]/PAYLOAD[1]/mysite:Call-Name[1]/Body[1]/ActionToTake[1]/Fields[1]/InternalSystemId[1]

Конечно, вы можете использовать любой префикс, который вам нравится.

Для выполнения # 2 есть несколько опций. Если элемент Call-Name не имеет родных элементов,или входит в стабильный порядок среди своих братьев и сестер, вы можете заменить * на его имя. Таким образом, XPath выберет любой дочерний элемент PAYLOAD[1], независимо от его имени или пространства имен:

/SomeMessage[1]/MessageDetails[1]/PAYLOAD[1]/*[1]/...

Другой вариант, если вы смелы и доверяетеНе говоря о структуре вашего входного XML, используйте //, чтобы пропустить этот элемент:

/SomeMessage[1]/MessageDetails[1]/PAYLOAD[1]//Body[1]/...

Если вам все еще нужно тестировать по имени, но не по пространству имен, вы можете использовать local-name() =:

/SomeMessage[1]/MessageDetails[1]/PAYLOAD[1]/*[local-name()='Call-Name']/Body[1]/...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...