Замена содержимого элемента значением произвольного атрибута с помощью XSLT 2.0

#xml #xslt #xslt-2.0

#xml #xslt #xslt-2.0

Вопрос:

Мне нужно заменить содержимое элемента значением произвольного атрибута, если элемент имеет этот атрибут. Мне нужно сделать это с помощью листа XSLT (2.0), но я понятия не имею, как я мог бы это сделать.

Например, допустим, у меня есть этот XML-документ.

 <?xml version="1.0" encoding="UTF-8"?>
<document> 
  Hi my name is <tag-A flag="Bob">Leopold</tag-A>
  and I'm fond of <tag-B flag="coding">literature</tag-B>
  unless in the <tag-C whatever="evening">morning</tag-C>
</document>
 

Затем xslt изменит содержимое любого элемента, имеющего flag атрибут, скажем, на значение этого атрибута и поместит все, заключенное в <p> тег. Это результат, который я получил бы в этом случае.

 <p>Hi my name is Bob
and I'm fond of coding
unless in the morning</p>
 

Как я могу это сделать?

Комментарии:

1. Ваш пример не «заменяет содержимое тега» — он заменяет весь элемент значением данного атрибута. В любом случае, это кажется довольно простой задачей XSLT; в чем именно заключается ваша трудность с этим?

2. Извините, я имел в виду элемент. -отредактировано — Да, я знаю, что это может быть базовый xslt, но, тем не менее, я начал изучать xslt вчера и понятия не имею, как это осуществить. <xsl:value-of select=»@flag»> получает все значения атрибутов флага, для этого все в порядке, но тогда? Честно говоря, я даже не знаю, с чего начать.

Ответ №1:

Это приведет к получению запрошенного вами результата:

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

<xsl:template match = "document">
  <p><xsl:apply-templates select="node()"/>
  </p>
</xsl:template>

<xsl:template match = "*[@flag]">
  <xsl:value-of select="@flag"/>
</xsl:template>

</xsl:stylesheet>
 

Обратите внимание, что @whatever благополучно игнорируется, но может быть легко свернуто.

Кроме того, я не думаю, что вы будете довольны документом с <p> в качестве самого внешнего элемента?

Комментарии:

1. ааааа теперь я понял, я не совсем хорошо понял, как использовать шаблоны. И элемент <p> был только для примера: P. На самом деле я работаю над довольно сложной задачей. Большое спасибо!

2. За исключением того, что третьим атрибутом в примере является «что угодно», а не «флаг» … было ли намерение заменить какой-либо атрибут или только атрибуты «флага»?

Ответ №2:

ПРИМЕЧАНИЕ: неясно, что вы имеете в виду, поскольку в заголовке вопроса указано «произвольный», а затем в тексте вопроса указан атрибут «флаг». ЕСЛИ ваш XML отображается только как show и вы хотите заменить любым атрибутом, а у вас есть только один, вы можете сделать это следующим образом (XSL 1.0 — это все, что требуется):

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

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

    <xsl:template match="text()">
        <xsl:copy/>
    </xsl:template>
    </xsl:stylesheet>
 

Вывод из вашего XML:

 <p> 
Hi my name is Bob
and I'm fond of coding
unless in the evening
</p>
 

Комментарии:

1. Если post ws используется только для замены атрибута «flag», это не сработает. Было неясно, является ли требованием только «флаг» или какой-либо атрибут.

2. При замене node() на element() вы можете даже опустить последний шаблон. — Я тоже не был так уверен в имени атрибута.