2013-02-13 10 views
1

У меня есть дерево xml с динамическим корневым элементом (а не статическим именем) и некоторыми дочерними элементами под этим корневым элементом. Теперь я хочу добавить к детям элемент во второй позиции с помощью скрипта xslt. Как мне это сделать?Как добавить узел во вторую позицию в корневой узел с помощью xslt

Пример: XML:

<root> 
    <element1> 
    <element1a> 
     .. 
    </element1a> 
    </element1> 
    <element2 name="exampleName">This is text.</element2> 
</root> 

должны быть преобразованы в

<root> 
    <element1> 
    <element1a> 
     .. 
    </element1a> 
    </element1> 
    <someNewElement>1234</someNewElement> 
    <element2 name="exampleName">This is text.</element2> 
</root> 

То, что я получил до сих пор состоит в следующем. Но с этим решением узел добавляется только в первую позицию. Мне нужно это на второй позиции.

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

<xsl:template match="/"> 
    <xsl:apply-templates select="/*"/> 
</xsl:template> 

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

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

</xsl:stylesheet> 

ответ

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

    <xsl:template match="/*/*[1]"> 
    <xsl:next-match /> 
    <xsl:element name="newElement">4711</xsl:element> 
    </xsl:template> 

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

</xsl:stylesheet> 

Это определяет шаблон, соответствующий первый дочерний элемент элемента документа, делает нормальную обработку шаблона идентичности (с использованием next-match), а затем вставляет свой новый элемент после него. Вы можете в качестве альтернативы сделать

<xsl:template match="/*/*[2]"> 
    <xsl:element name="newElement">4711</xsl:element> 
    <xsl:next-match /> 
</xsl:template> 

, чтобы соответствовать второму ребенку и вставить элемент перед ним. Разница между ними очевидна, если <root> имеет только один дочерний элемент, и в этом случае версия /*/*[1] будет вставлять newElement, но /*/*[2] не будет.

+0

Это сработало отлично. Большое спасибо! – Hauke

1

Как об этом:

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

    <xsl:template match="/*/*[1]"> 
    <xsl:call-template name="copy" /> 
    <newElement>4711</newElement> 
    </xsl:template> 

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

</xsl:stylesheet> 

При запуске на своем входе образца, это производит:

<root> 
    <element1> 
    <element1a> 
     .. 
    </element1a> 
    </element1> 
    <newElement>4711</newElement> 
    <element2 name="exampleName">This is text.</element2> 
</root> 

И если вы на самом деле используете XSLT 2.0, вы должны быть в состоянии использовать <xsl:next-match /> вместо <xsl:call-template name="copy" /> и удалите атрибут name из другого шаблона.

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