Xpath с пространством имен по умолчанию

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

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        <entry xml:base="https://www.website.com" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
          <id>A</id>
          <title type="text"></title>
          <updated>2015-07-21T02:40:30Z</updated>
          <author>
            <name />
          </author>
          <link rel="edit" title="Application" href="A(1347)" />
          <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/b" type="application/atom+xml;type=feed" title="B" href="A(1347)/B" />
          <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/C" type="application/atom+xml;type=feed" title="C" href="A(1347)/C" />
          <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/D" type="application/atom+xml;type=entry" title="D" href="A(1347)/D" />
          <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/E" type="application/atom+xml;type=feed" title="E" href="A(1347)/E">
            <m:inline>
              <feed>
                <title type="text">E</title>
                <id>1347</id>
                <updated>2015-07-21T02:40:30Z</updated>
                <link rel="self" title="E" href="A(1347)/E" />
                <entry>
                  <id>www.website.com/</id>
                  <title type="text"></title>
                  <updated>2015-07-21T02:40:30Z</updated>
                  <author>
                    <name />
                  </author>
                  <link rel="edit" title="E" href="E(4294)" />
                  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/A" type="application/atom+xml;type=entry" title="Application" href="E(4294)/A" />
                  <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/D" type="application/atom+xml;type=entry" title="D" href="E(4294)/D" />
                  <category term="APIModel.FileBaseDocuments" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
                  <content type="application/xml">
                    <m:properties>
                      <d:ID m:type="Edm.Int32">4294</d:ID>
                      <d:Type>123</d:Type>
                    </m:properties>
                  </content>
                </entry>
                 <entry>
              <id>www.website.com</id>
              <title type="text"></title>
              <updated>2015-07-21T02:40:30Z</updated>
              <author>
                <name />
              </author>
              <link rel="edit" title="E" href="E(4295)" />
              <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/A" type="application/atom+xml;type=entry" title="A" href="E(4295)/A" />
              <link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/D" type="application/atom+xml;type=entry" title="D" href="E(4295)/D" />
              <category term="APIModel.FileBaseDocuments" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
              <content type="application/xml">
                <m:properties>
                  <d:ID m:type="Edm.Int32">4295</d:ID>
                  <d:Type>456</d:Type>
                </m:properties>
              </content>
             </entry>
           </feed>
          </m:inline>
        </link>
      </entry>

Я хочу получить все значения внутри "m:properties/d:ID m:type="Edm.Int32" (в данном случае 4294), но мне не повезло. Таким образом, для одного файла будет один "канал" заполненный несколькими тегами "entry". Внутри этих тегов будет один "m:properties/d:ID m:type="Edm.Int32", который мне нужно получить. Любое предложение о том, каким будет правильный xPath для этой ситуации?


person XSL Noob    schedule 21.07.2015    source источник
comment
Пожалуйста, покажите нам полный код.   -  person Lingamurthy CS    schedule 21.07.2015
comment
Привет, я добавил остальную часть кода. Дайте мне знать, поможет ли это вообще.   -  person XSL Noob    schedule 21.07.2015


Ответы (2)


Вместо того, чтобы прибегать к независимому от пространства имен xml с помощью local-name(), почему бы не зарегистрировать пространство имен для пространства имен по умолчанию, например. префикс x для xmlns:x="http://www.w3.org/2005/Atom", и тогда ваш Xpath будет выглядеть примерно так:

//x:feed/x:entry/x:content/m:properties/d:ID[@m:type='Edm.Int32']

Подход local-name() более подробный:

//*[local-name()='feed']/*[local-name()='entry']/*[local-name()='content']
 /*[local-name()='properties']/*[local-name()='ID' and @m:type='Edm.Int32']

Пример обоих подходов здесь

person StuartLC    schedule 21.07.2015
comment
Спасибо Стюарт! Объявление пространства имен в XSLT было лучшим вариантом. Я очень ценю это! - person XSL Noob; 21.07.2015
comment
Рад помочь. Подход local-name() также будет соответствовать любому пространству имен, что будет проблематично, если есть узлы с одинаковым именем в разных пространствах имен — в этом случае вам также потребуется добавить and namespace-uri()='http://www.w3.org/2005/Atom' в качестве дополнительного предиката. Пространства имен намного понятнее для читателя IMO. - person StuartLC; 21.07.2015

Используйте атрибут @exclude-result-prefixes, чтобы отфильтровать посторонние пространства имен в выводе. Вам не нужно объявлять http://www.w3.org/2005/Atom. в вашем преобразовании, если только вам это не нужно для других целей, но даже в этом случае это, вероятно, хорошая вещь.

Просто сопоставьте выражение m:properties/d:ID[@m:type='Edm.Int32'], чтобы получить необходимые данные.

Например, это преобразование применительно к данному входному документу....

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
  xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
  xmlns:atom="http://www.w3.org/2005/Atom"
  version="2.0"
  exclude-result-prefixes="xsl d m atom">

<xsl:output encoding="utf-8" omit-xml-declaration="yes" indent="yes" />

<xsl:template match="/">
  <Edm.Int32s>
    <xsl:apply-templates />
  </Edm.Int32s>
</xsl:template>

<xsl:template match="*">
  <xsl:apply-templates />
</xsl:template>

<xsl:template match="text()" />

<xsl:template match="m:properties/d:ID[@m:type='Edm.Int32']">
  <value><xsl:value-of select="text()" /></value>
</xsl:template>  

</xsl:stylesheet>

... дает результат ....

<edm.int32s>
  <value>4294</value>
  <value>4295</value>
</edm.int32s>

Примечание

Из ваших вопросительных тегов я предположил, что вам нужно преобразование XSLT. Если вы просто хотите, чтобы простое выражение XPath применялось непосредственно к документу, вы могли бы использовать...

//m:properties/d:ID[@m:type='Edm.Int32']/text()

(передавая, конечно, объявления пространств имен для m и d).

person Sean B. Durkin    schedule 21.07.2015