2015-05-20 2 views
3

Это мой XML:Изменение значения атрибута в зависимости от значения второго атрибута одного и того же элемента

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <trans> 
     <language type="lang" lang="DE"/> 
    </trans> 
    <trans> 
     <language type="lang" lang="EN"/> 
    </trans> 
</root> 

Моя цель состоит в том, чтобы заменить значение атрибута «тип» в зависимости от значения указанный в атрибуте «lang».

Это желаемый результат:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <trans> 
     <language type="German" lang="DE"/> 
    </trans> 
    <trans> 
     <language type="English" lang="EN"/> 
    </trans> 
</root> 

Я начал со следующим, но не получить дальше в этом пункте:

<xsl:template match="language"> 
    <xsl:choose> 
    <xsl:when test="@lang=DE"> 
     <xsl:attribute name="type"> 
     <xsl:value-of select="'German'"/> 
    <xsl:apply-templates/> 
    </xsl:when> 
    <xsl:otherwise> 
    ??? 

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

+0

Пожалуйста, укажите XSLT 1.0 или 2,0. - Сколько языков в целом? –

+0

Это XSLT 2.0, и количество языков может варьироваться. – bimmer

+0

Что значит «это может измениться»? Если вы хотите добавить значение к каждому коду, вы должны подготовить коды привязки списка к значениям. Я спрашиваю, сколько записей будет в этом списке. –

ответ

1

Попробуйте эти 3 шаблоны (первый из них является шаблон идентичности, второй будет «съедать» все @type и третий один сгенерирует оба атрибута снова, на основе @type):

<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="//language/@type"/> 

<xsl:template match="//language/@lang"> 
    <xsl:attribute name="lang"> 
    <xsl:value-of select="."/> 
    </xsl:attribute> 
    <xsl:attribute name="type"> 
    <xsl:choose> 
     <xsl:when test=".='DE'">German</xsl:when> 
     <xsl:when test=".='EN'">English</xsl:when> 
     <xsl:otherwise>Other</xsl:otherwise> 
    </xsl:choose> 
    </xsl:attribute> 
</xsl:template> 
+0

Точно, к чему я стремился. Благодарю. – bimmer

1

XSLT :

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:data="data"> 
    <xsl:output method="xml" indent="yes"/> 
    <data:languages> 
    <lang key="DE" value="German"/> 
    <lang key="EN" value="English"/> 
    </data:languages> 

    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="language"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*[name() != 'type']"/> 
     <xsl:attribute name="type"> 
     <xsl:value-of select="document('')//lang[@key = current()/@lang]/@value"/> 
     </xsl:attribute> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Выход:

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <trans> 
    <language lang="DE" type="German" /> 
    </trans> 
    <trans> 
    <language lang="EN" type="English" /> 
    </trans> 
</root> 
0

Если есть только три языка, и вы используете только этот перевод я n одно место, то xsl:choose делает привлекательный выбор. Конечно, это может быть реализовано гораздо проще, как:

XSLT 1.0 или 2.0

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

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="language/@type"> 
    <xsl:attribute name="type"> 
     <xsl:choose> 
      <xsl:when test="../@lang='DE'">German</xsl:when> 
      <xsl:when test="../@lang='EN'">English</xsl:when> 
      <xsl:when test="../@lang='FR'">French</xsl:when> 
     </xsl:choose> 
    </xsl:attribute> 
</xsl:template> 

</xsl:stylesheet> 

С большим количеством языков, и/или, если вам нужно повторно использовать код в нескольких местах, это может быть более удобно перейти к поиску:

XSLT 2,0

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

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:variable name="languages"> 
    <language code="DE">German</language> 
    <language code="EN">English</language> 
    <language code="FR">French</language> 
</xsl:variable> 

<xsl:key name="lang" match="language" use="@code" /> 

<xsl:template match="language/@type"> 
    <xsl:attribute name="type"> 
     <xsl:value-of select="key('lang', ../@lang, $languages)"/> 
    </xsl:attribute> 
</xsl:template> 

</xsl:stylesheet> 
Смежные вопросы