2012-05-24 4 views
3

Мне нужно преобразовать эту структуруКак преобразовать структуру XML с помощью XSLT-1,0

<A> 
<B>value1</B> 
</A> 
<A> 
<B>value2</B> 
</A> 

в

<A> 
<B>value1<B> 
<B>value2<B> 
</A> 

Что лучшее решение с использованием XSLT-1.0? Спасибо!

PS: Я попробовал этот код:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> 
<xsl:key name="group_a" match="//A" use="B"/> 
<xsl:template match="/Test"> <a-node> <xsl:for-each select="//A"> <b-node> 
<xsl:value-of select="//A/B"/> </b-node> </xsl:for-each> </a-node> 
</xsl:template> 
</xsl:stylesheet> 

но он возвращает только первое значение:

<?xml version="1.0" encoding="utf-8"?> <a-node mlns:fo="http://www.w3.org/1999/XSL/Format"> <b-node>value1</b-node> <b-node>value1</b-node> </a-node> 

, но мне нужно:

<?xml version="1.0" encoding="utf-8"?> <a-node xmlns:fo="http://www.w3.org/1999/XSL/Format"> <b-node>value1</b-node> <b-node>value2</b-node> </a-node> 

ответ

1

Так как кажется, вам нужно свернуть все дети под одним узлом, то вам не нужен foreach на «A», вы можете напрямую перейти к детям «B»

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       version="1.0"> 
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" /> 
    <xsl:template match="/"> 
     <A> 
      <xsl:for-each select="//A/B"> 
       <B> 
        <xsl:value-of select="./text()"/> 
       </B> 
      </xsl:for-each> 
     </A> 
    </xsl:template> 
</xsl:stylesheet> 

EDIT Согласно @ комментарий Шона, обратите внимание, что // никогда не должны использоваться в реальной жизни. Замените // на путь от вашего реального элемента Element.

+0

Функционально корректный, но неэффективный. Лучше использовать стиль шаблона и избегать ненужного использования оператора //. –

+0

@Sean - уверенный - Согласился никогда не использовать //, но не имел выбора, так как образец XML xml не имеет корневого элемента :) – StuartLC

2

Этот стиль-лист ...

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       version="1.0"> 
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" /> 
    <xsl:template match="/"> 
     <A> 
     <xsl:apply-templates select="*/A/B"/> 
     </A> 
    </xsl:template> 

    <xsl:template match="B"> 
     <B><xsl:value-of select="."/></B> 
    </xsl:template> 
</xsl:stylesheet> 

... трансформирует ...

<root> 
<A> 
<B>value1</B> 
</A> 
<A> 
<B>value2</B> 
</A> 
</root> 

... в это ...

<A><B>value1</B><B>value2</B></A> 
0

Это преобразование использует один из самых фундаментальных шаблонов проектирования 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="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="A[1]"> 
    <A> 
    <xsl:apply-templates select="node()|following-sibling::A/node()"/> 
    </A> 
</xsl:template> 
<xsl:template match="A"/> 
</xsl:stylesheet> 

Когда это преобразование применяется на следующий документ XML (полученный путем обертывания предоставленный фрагмент XML в один верхний элемент - в сделать это хорошо сформированный XML документ):

<t> 
    <A> 
     <B>value1</B> 
    </A> 
    <A> 
     <B>value2</B> 
    </A> 
</t> 

разыскиваемый, правильный результат получается:

<t> 
    <A> 
     <B>value1</B> 
     <B>value2</B> 
    </A> 
</t> 
Смежные вопросы