访问xsl中的xml属性

时间:2010-07-31 18:06:47

标签: php xslt

我有这个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 个答案:

答案 0 :(得分:5)

以下内容可行。

源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>

编辑:修改了标题模板,使用xml:lang属性作为类属性,因此您可以使用CSS设置样式。如果您需要更复杂的样式,请编写与该属性匹配的另一个模板(如Volker所示)。

答案 1 :(得分:2)

您可以尝试for-each

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

我不是100%肯定,但我认为value-of只会获得一个元素的值,如果选择了多个元素,它只会获得第一个元素的值。< / p>

答案 2 :(得分:2)

标题模板将是执行此操作的最佳方式:

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

可以使用xsl:for-each来实现相同目标,但模板是惯用的xsl。

答案 3 :(得分:1)

您可以拥有多个与特定节点匹配的模板。在这种情况下,匹配模板被优先化,并且仅使用具有最高优先级的模板。如果您没有专门设置优先级,则有内置规则来确定优先级,请参阅5.5 Conflict Resolution for Template Rules

E.g。如果你有两个模板

  1. &lt; xsl:template match =“title”&gt; ...&lt; / xsl:template&gt;
  2. &lt; xsl:template match =“title [@xml:lang ='ar']”&gt; ...&lt; / xsl:template&gt;
  3. 他们都匹配<title xml:lang="ar">أربيك</title> 但是测试xml:lang属性(模板#2)的那个“比最常见的模式更具体”,并且比仅匹配所有&lt; title&gt;的模板获得更高的优先级。元素(模板#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>
    

答案 4 :(得分:1)

可能最短,完整的解决方案,也完全符合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>

答案 5 :(得分:0)

我认为你的第一次尝试是在正确的方向:只需复制@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>

正确输入(来自Dimitre):

<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>