доступ к атрибутам xml в xsl - PullRequest
2 голосов
/ 31 июля 2010

у меня есть этот XML-код:

<title xml:lang="ar">أربيك</title>
<title xml:lang="en">English</title>

который я форматирую в xsl:

<div class="title">
        <xsl:value-of select="root/title"/>
</div>

однако, это ^ отображает только арабское название, а не английское. я попробовал этот код:

<div class="title">
        <xsl:attribute name="xml:lang"><xsl:value-of select="root/title"/> </xsl:attribute>
</div>

но с этим кодом ^ он вообще не отображает заголовки. Как правильно отображать английские и арабские названия?

Ответы [ 6 ]

5 голосов
/ 31 июля 2010

Будет работать следующее.

Исходный XML:

$xmlDoc = <<< XML
<titles>
    <title xml:lang="ar">أربيك</title>
    <title xml:lang="en">English</title>
</titles>
XML;

Таблица стилей XSL с шаблоном, соответствующим любым узлам заголовка в документе

$xslDoc = <<< XSL
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:template match="title">
        <div class="{@xml:lang} title">
            <xsl:value-of select="."/>
        </div>
    </xsl:template>

</xsl:stylesheet>
XSL;

И преобразование с помощью PHP:

$xml = new DOMDocument();
$xml->loadXML($xmlDoc);
$xsl = new DOMDocument;
$xsl->loadXML($xslDoc);
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
echo $proc->transformToXML($xml);

даст:

<?xml version="1.0"?>
<h1>Titles</h1>
    <div class="ar title">أربيك</div>
    <div class="en title">English</div>

EDIT : измененный шаблон заголовка для использования атрибута xml: lang в качестве атрибута класса, поэтому вы можете стилизовать его с помощьюCSS.Если вам нужно более сложное моделирование, напишите другой шаблон, который соответствует атрибуту (как показано Volker).

2 голосов
/ 31 июля 2010

Шаблон заголовка будет лучшим способом сделать это:

<xsl:template match="title">
  <div class="title">
    <xsl:value-of select="." />
  </div>
</xsl:template>

Вы можете использовать xsl:for-each для достижения того же, но шаблон - идиоматический xsl.

2 голосов
/ 31 июля 2010

Вы можете попробовать для каждого :

<xsl:for-each select="root/title">
    <xsl:value-of select="."/>
</xsl:for-each>

Я не уверен на 100%, но думаю, value-of получит только значение один элемент, и если выбрано несколько, он просто получает значение первого.

1 голос
/ 01 августа 2010

Вероятно, самое короткое, полное решение, которое также полностью соответствует духу XSLT, - это следующее :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="title">
    <div class="title">
            <xsl:value-of select="."/>
    </div>
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к следующему XMLдокумент (просто завершение предоставленного фрагмента XML в один верхний элемент):

<titles>
    <title xml:lang="ar">أربيك</title>
    <title xml:lang="en">English</title>
</titles>

желаемый результат получается :

<div class="title">أربيك</div>
<div class="title">English</div>
1 голос
/ 01 августа 2010

Вы можете иметь более одного шаблона, который соответствует конкретному узлу. В этом случае соответствующие шаблоны имеют приоритет, и используется только шаблон с наивысшим приоритетом. Если вы специально не устанавливаете приоритет, существуют встроенные правила для определения приоритета, см. 5.5 Разрешение конфликтов для шаблонных правил .

например. если у вас есть два шаблона

  1. ... </ xsl: template>
  2. ... </ xsl: template>

они оба совпадают <title xml:lang="ar">أربيك</title>.
Но тот, который тестирует атрибут xml: lang (шаблон # 2), «более специфичен, чем самый распространенный тип шаблона» и получает более высокий приоритет, чем шаблон, который просто соответствует всем элементам (шаблон # 1). Поэтому выбран шаблон № 2.
Для <title xml:lang="en">title 2</title> есть только один соответствующий шаблон (шаблон # 1), который поэтому выбран.

автономный пример:

<?php
$proc = <<< XSL
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="title">
    <h2>template #1: <xsl:value-of select="."/></h2>
  </xsl:template>

  <xsl:template match="title[@xml:lang='ar']">
    <h1>template #2: <xsl:value-of select="."/></h1>
  </xsl:template>

</xsl:stylesheet>
XSL;
$proc = getProcessor($proc);

$doc = <<< XML
<titles>
    <title xml:lang="ar">أربيك</title>
    <title xml:lang="en">english title</title>
</titles>
XML;
$doc = getDocument($doc);

echo $proc->transformToXML($doc);


function getDocument($xml) {
  $doc = new DOMDocument;
  $doc->loadxml($xml);
  return $doc;
}

function getProcessor($xml) {
  $proc = new XSLTProcessor;
  $proc->importStylesheet(getDocument($xml));
  return $proc;
}

печать

<?xml version="1.0"?>

    <h1>template #2: أربيك</h1>
    <h2>template #1: english title</h2>
0 голосов
/ 02 августа 2010

Я думаю, что ваша первая попытка была в правильном направлении: просто скопируйте @xml: lang и примените стиль CSS позже. Итак, эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="titles">
        <html>
            <xsl:apply-templates/>
        </html>
    </xsl:template>
    <xsl:template match="title">
        <div class="title">
            <xsl:copy-of select="@xml:lang"/>
            <xsl:value-of select="."/>
        </div>
    </xsl:template>
</xsl:stylesheet>

При правильном вводе (от Димитра):

<titles>
    <title xml:lang="ar">أربيك</title>
    <title xml:lang="en">English</title>
</titles>

Выход:

<html>
<div class="title" xml:lang="ar">أربيك</div>
<div class="title" xml:lang="en">English</div>
</html>

Или эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="titles">
        <html>
            <xsl:apply-templates/>
        </html>
    </xsl:template>
    <xsl:template match="title">
        <div class="title" lang="{@xml:lang}">
            <xsl:value-of select="."/>
        </div>
    </xsl:template>
</xsl:stylesheet>

Выход:

<html>
<div class="title" lang="ar">أربيك</div>
<div class="title" lang="en">English</div>
</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...