Переименование всех дочерних узлов узла XML с использованием XSLT - PullRequest
0 голосов
/ 31 мая 2018

У меня есть XML-файл со следующей структурой.

<Telefon>
    <area>0123</area>
    <number>456</number>
    <extension>789</extension>
</Telefon>
<Fax>
    <area>3210</area>
    <number>654</number>
    <extension>1098</extension>
</Fax>

Я хотел бы преобразовать это с помощью XSLT в следующее

<telefon-area>0123</area>
<telefon-number>456</number>
<telefon-extension>789</extension>
<fax-area>3210</area>
<fax-number>654</number>
<fax-extension>1098</extension>

Я дошел до использования копиишаблонов, и хотя я мог бы написать шаблоны для изменения этих полей вручную, я хотел бы написать только один, добавив префикс telefon или fax к каждому дочернему узлу предыдущих узлов Telefon и Fax.

Этоструктура, которую я придумала до сих пор:

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

<!--The next template removes the telefon tag but I do not know how to modify the child nodes to extend them with the telefon- prefix.-->
<xsl:template match="Telefon">
    <xsl:apply-templates select="@*|node()"/> 
</xsl:template>

Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 31 мая 2018

Чтобы соответствовать потомкам узла Telefon, вы можете сделать это ...

<xsl:template match="Telefon/*">

И вы можете расширить его так, чтобы обрабатывать Fax тоже

 <xsl:template match="Telefon/*|Fax/*">

В рамках этого вы можете использовать xsl:element вместе с local-name() для создания нового имени элемента.

Попробуйте это XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes" />

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

    <!--The next template removes the telefon tag but I do not know how to modify the child nodes to extend them with the telefon- prefix.-->
    <xsl:template match="Telefon|Fax">
        <xsl:apply-templates /> 
    </xsl:template>

    <xsl:template match="Telefon/*|Fax/*">
        <xsl:element name="{local-name(..)}-{local-name()}">
            <xsl:apply-templates select="@*|node()" />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Примечание в шаблоне, соответствующем Telefon, вам действительно нужно сделать <xsl:apply-templates />, так как вы, вероятно, хотите игнорировать любые атрибуты на Telefon, если они есть.

В качестве альтернативы, вы можете использовать «режим», если у вас есть другие элементы, в дополнение к Telefon и Fax вы тоже хотели изменить

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes" />

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

    <!--The next template removes the telefon tag but I do not know how to modify the child nodes to extend them with the telefon- prefix.-->
    <xsl:template match="Telefon|Fax">
        <xsl:apply-templates mode="child" /> 
    </xsl:template>

    <xsl:template match="*" mode="child">
        <xsl:element name="{local-name(..)}-{local-name()}">
            <xsl:apply-templates select="@*|node()" />
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Обратите внимание, что это не делает имя полностью строчным.Если вы этого хотите, то это будет зависеть от того, используете ли вы XSLT 2.0 или XSLT 1.0.

В идеале вы можете использовать XSLT 2.0 и сделать это ...

 <xsl:element name="{lower-case(local-name(..))}-{local-name()}">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...