Не удается выполнить запрос с использованием XPath, когда элемент данных имеет атрибут **xmlns=**

Мне трудно запросить значение значения элемента данных, когда в нем есть атрибут xmlns="..." и его родительский элемент. Следующий пример является частью ответа SOAP, и я хочу получить значение имени и фамилии, используя XPATH /PartyInq_v2Response/PartyInq_v2Rs_Type/*[local-name()="person"]/firstName ' . Но ничего не возвращает. Он может вернуть значение, если я удалил все xmlns="..." из xml перед запросом. Кто-нибудь знает, как напрямую запросить имя из примера?

<PartyInq_v2Response xmlns="urn:Somewhere.Int" xmlns:q2="http://SomewhereOps.v20120719" xmlns:q10="http://SomewhereTypes.v20120719.GenericTypes">
    <PartyInq_v2Rs_Type>
        <q2:person>
            <firstName xmlns="http://SomewhereTypes.v20120719.Types">somebody</firstName>
            <lastName xmlns="http://SomewhereTypes.v20120719.Types">nobody</lastName>           
        </q2:person>
    </PartyInq_v2Rs_Type>
</PartyInq_v2Response>

Спасибо

Lu


person Yadong    schedule 03.05.2013    source источник


Ответы (1)


Непонятно, какой процессор xslt вы используете. Но вы должны сделать все используемые пространства имен известными для xlst.

Следующий xlst будет делать:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:s="urn:Somewhere.Int" 
            xmlns:q2="http://SomewhereOps.v20120719"
            xmlns:q10="http://SomewhereTypes.v20120719.GenericTypes"
            xmlns:t="http://SomewhereTypes.v20120719.Types">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/" >
        <xsl:value-of select="/s:PartyInq_v2Response/s:PartyInq_v2Rs_Type/q2:person/t:firstName"/>
    </xsl:template>
</xsl:stylesheet>

Если URL-адрес пространства имен неизвестен, вы можете использовать local-name().

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
             xmlns:s="urn:Somewhere.Int" >
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/" >
        <xsl:value-of select="/s:PartyInq_v2Response/*[local-name() = 'PartyInq_v2Rs_Type']/*[local-name() = 'person']/*[local-name()='firstName']"/>
    </xsl:template>
</xsl:stylesheet>
person hr_117    schedule 03.05.2013
comment
Спасибо за помощь. Я использую XMLSpy для тестирования. Есть ли способ игнорировать пространства имен вместо того, чтобы определять их в xlst? поскольку мы используем инструмент для создания схемы SOAP, которая будет использоваться для создания ответного сообщения SOAP. Каждый раз, когда мы воссоздаем эти схемы, внутреннее пространство имен (например, q10, q2) может отличаться каждый раз во время регенерации схем, т.е. q10 изменено на q20. что очень затруднит определение (жесткий код) пространства имен в моем xslt. - person Yadong; 03.05.2013
comment
Изменился только префикс или URL? Если какой-либо префикс изменен, это не имеет значения. Если URL-адрес изменен, вы можете использовать локальное имя, как вы уже делали. (См. обновление.) - person hr_117; 04.05.2013
comment
Спасибо, hr_117 :) Но пока xmlns=blabla в XML как атрибут, Local-name() не работает, по крайней мере, в XMLSPy. Вот почему я публикую вопрос здесь. Если я уберу эти атрибуты, неважно, есть префикс или нет, он точно сработает. Так что, может быть, я должен просто использовать первый, который вы мне показали. - person Yadong; 04.05.2013