2015-12-06 5 views
0

Есть в любом случае преобразования XML-таким образом, чтобы значения в пределах каждого элемента становятся атрибутами этого элемента, например,значения Преобразование XML в атрибуты

<example> 
    <abc>12</abc> 
    <def>hello</def> 
</example> 

становится:

<example> 
    <abc val=12/> 
    <def val=hello/> 
</example> 

, но все остальное оставил тот же

Извините забыл сказать, что я идеально хотел бы сценарий, который достигает этого, независимо от того, какой xml вы ему даете.

+0

XML - это ** очень ** гибкий формат и может иметь множество вариантов. Когда вы запрашиваете преобразование «*, которое достигает этого, независимо от того, какой xml вы его даете», вам нужно предоставить больше правил для обработки вариантов. Например, элемент уже может иметь атрибут с именем 'val'. Или это может иметь смешанный контент. И смешанный контент может иметь более одного текстового узла. –

+0

Да, мои извинения, я имею в виду любой XML-документ, который может иметь любые элементы, но ни один из этих элементов не имеет атрибутов, но некоторые из них имеют значения. – bdanger

ответ

1

Нечто подобное должно работать:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" omit-xml-declaration="no" encoding="UTF-8" indent="yes" /> 

    <xsl:template match="example"> 
    <xsl:element name="{name()}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 

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

    <xsl:element name="{name()}"> 
      <xsl:attribute name="val"><xsl:value-of select="."/></xsl:attribute> 
     </xsl:element> 
    </xsl:template> 

</xsl:transform> 

Однако, в зависимости от структуры вашей реальной жизни вход, возможно, потребуется изменить селекторы шаблона.

0

Написать шаблон

<xsl:template match="example/*[not(*)]"> 
    <xsl:element name="{name()}" namespace="{namespace-uri()}"> 
    <xsl:attribute name="val" select="."/> 
    </xsl:element> 
</xsl:template> 

плюс шаблон тождественное преобразование конечно

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

Если вы хотите, чтобы преобразовать все элементы, не имеющие дочерние элементы в формате <foo val="..."/> затем изменить шаблон соответствия шаблона от <xsl:template match="example/*[not(*)]"> до <xsl:template match="*[not(*)]">. Также обратите внимание, что я использовал синтаксис XSLT 2.0 <xsl:attribute name="val" select="."/>, с процессором XSLT 1.0 вам понадобится <xsl:attribute name="val"><xsl:value-of select="."/></xsl:attribute>.

Что касается рабочего подхода для любого документа XML, ну, если у вас есть <foo><bar><baz>foobar</baz></bar><bar>value</bar></foo>, тогда простой подход вызовет ошибку, поскольку создание атрибута произойдет после создания дочернего элемента. Непонятно, какой результат результата вы хотите, поэтому вам нужно будет отредактировать свой вопрос и показать нам более подробную информацию о возможных входных и желаемых образцах результатов.

+0

Я буду соответствовать всем дочерним элементам ('*'), не имеющим дочерних элементов 'not (*)' элементов 'example'. –

Смежные вопросы