Xpath поиск по сцепленным значениям предков - PullRequest
1 голос
/ 09 декабря 2011

У меня есть XML-файл структуры сайта, и я хотел бы найти узел на основе объединенных значений этого узла и его родителей.

Вот пример XML:

<site>
    <page id="1">
        <url></url>
        <url>home</url>
        <page id="2">
            <url>about-us</url>
        </page>
        <page id="3">
            <url>locations</url>
            <page id="4">
                <url>scotland</url>
                <page id="5">
                    <url>glasgow</url>
                </page>
                <page  id="6">
                    <url>edinburgh</url>
                </page>
            </page>
        </page>
    </page>
</site>

Так что, если бы URL был /locations/scotland/edinburgh, я бы хотел выбрать страницу id=6.

Я надеюсь, что запрос XPath может быть чем-то вроде ...

//page[fn:string-join(ancestor-or-self::page[
                url='locations/scotland/edinburgh'],'/')]

Любые советы будут потрясающими.

1 Ответ

1 голос
/ 09 декабря 2011

Сначала необходимо разделить URL-адрес на составляющие его пути (что легко сделать с помощью XPath 2.0, но не совсем в XPath 1.0), а затем сконструировать и оценить это выражение XPath :

//page[url='locations']
       /page[url='scotland']
          /page[url='edinburgh']
            /@id

Выбирает необходимый атрибут id.

Строковое значение этого атрибута id (6) является результатом вычисления следующего выражения XPath :

string(//page[url='locations']
          /page[url='scotland']
             /page[url='edinburgh']
               /@id
       )

Обновление :

Существует единственное универсальное выражение XPath 2.0, в котором задан параметр с именем $pUrl, содержащий URL-адрес, который находит все элементы page стребуемое свойство:

//page
   [ends-with(
              concat('/',
                     string-join(ancestor-or-self::*/url, '/')
                    ),
              $pUrl
             )
   ]

проверка XSLT 2.0 :

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pUrl" select="'/locations/scotland/edinburgh'"/>

 <xsl:template match="/">

  <xsl:sequence select=
   "//page
       [ends-with(
                  concat('/',
                         string-join(ancestor-or-self::*/url, '/')
                        ),
                  $pUrl
                 )
       ]
   "/>
 </xsl:template>
</xsl:stylesheet>

**when this transformation is applied on the provided XML document**:

<site>
    <page id="1">
        <url></url>
        <url>home</url>
        <page id="2">
            <url>about-us</url>
        </page>
        <page id="3">
            <url>locations</url>
            <page id="4">
                <url>scotland</url>
                <page id="5">
                    <url>glasgow</url>
                </page>
                <page  id="6">
                    <url>edinburgh</url>
                </page>
            </page>
        </page>
    </page>
</site>

выбран требуемый, правильный page элемент и выводится :

<page id="6">
    <url>edinburgh</url>
</page>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...