2014-01-31 6 views
-3

Мой XML выглядит следующим образом: я хочу преобразовать его в упомянутый ожидаемый формат xml с помощью XSLT 2.0. child1 и child2 - это всего лишь образцы, в реальном XML может быть несколько таких узлов с разными именами. Я новичок в очень XslХотите преобразовать XML, содержащий смешанный контент

<?xml version="1.0" encoding="utf-8" ?> 
<properties xmlns="http://www.sss.org"> 
My Parent level text 1 <b> i am bold</b> not bold 
<child1> 
text1 of first child 
<child1val attribute1="testval">36-37</child1val> 
text2 of child <sub> subscript</sub> 
</child1>  
<child2> 
text1 of first child2 
<child2val attribute1="testval">444</child2val> 
<child2val>555</child2val> 
text2 of child2 
</child2> 
My Parent level text3 in <b> i am bold</b> 
</properties> 

ожидаемый результат:

<properties xmlns="http://www.sss.org"> 
<text> 
My Parent level text 1 <b> i am bold</b> not bold 
</text> 
<child1> 
<text> text1 of first child </text> 
<child1val attribute1="testval">36-37</child1val> 
<text> text2 of child <i> i m italic</i></text> 
</child1>  
<child2> 
<text> text1 of second child2</text> 
<child2val attribute1="testval">444</child2val> 
<child2val>555</child2val> 
<text> text2 of child2</text> 
</child2> 
My Parent level text3 in <b> i am bold</b> 

ответ

2

Путь вы отступом ваш XML не помогает с тем, как вы задали этот вопрос. Например, рассмотрите эту сокращенную выборку вашего XML.

<properties> 
My Parent level text 1 <b> i am bold</b> not bold 
<child1> 
text1 of first child 
</child1>  
</properties> 

Как это выкладывается, кажется, подразумевает свойства элемент имеет двоих детей. Но это не так, у него четверо детей. Более четкие отступы бы как этот

<properties> 
    My Parent level text 1 
    <b> i am bold</b> 
    not bold 
    <child1> 
     text1 of first child 
    </child1>  
</properties> 

И это выглядит как текст элемента необходимо только окружать первые три детей, но не элемент child1. Не ясно, почему б получает окружать в текста элемента, но child1 не делает, но я предполагаю, что это происходит потому, что б и ясуб?) Являются «HTML» элементы, но ребенок1 нет.

Делая это предположение, вероятно, можно решить эту проблему с помощью XSL: для-каждой группе команду в XSLT 2.0, вместе с его группы смежного атрибут. Вы группируя соседние узлы, если они представляют собой текстовые узлы или б или я или суб, поэтому команда будет выглядеть следующим образом

<xsl:for-each-group select="node()" 
        group-adjacent="boolean(self::b|self::i|self::sub|self::text())"> 

В рамках этого, вы можете проверить ток-группировки -key() функция, чтобы определить, то ли нужно окружить группу с текста элемента

<xsl:choose> 
     <xsl:when test="current-grouping-key()"> 
      <text> 
      <xsl:apply-templates select="current-group()" /> 
      </text> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:apply-templates select="current-group()" /> 
     </xsl:otherwise> 
    </xsl:choose> 

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

<xsl:template match="*[*]"> 

Других узлы вошьют и скопированный с XSLT identity template.

Попробуйте XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.sss.org" xmlns="http://www.sss.org"> 

    <xsl:output method="xml" indent="yes" /> 
    <xsl:strip-space elements="*" /> 

    <xsl:template match="*[*]"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:for-each-group select="node()" group-adjacent="boolean(self::b|self::i|self::sub|self::text())"> 
     <xsl:choose> 
      <xsl:when test="current-grouping-key()"> 
       <text> 
       <xsl:apply-templates select="current-group()" /> 
       </text> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:apply-templates select="current-group()" /> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:copy> 
    </xsl:template> 

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

(Обратите внимание на использование пространств имен здесь, как и все элементы в вашем XML в пространстве имен).

Это должен вывести следующие

<properties xmlns="http://www.sss.org"> 
    <text> 
     My Parent level text 1 <b> i am bold</b> not bold 
    </text> 
    <child1> 
     <text> 
     text1 of first child 
     </text> 
     <child1val attribute1="testval">36-37</child1val> 
     <text> 
     text2 of child <sub> subscript</sub> 
     </text> 
    </child1> 
    <child2> 
     <text> 
     text1 of first child2 
     </text> 
     <child2val attribute1="testval">444</child2val> 
     <child2val>555</child2val> 
     <text> 
     text2 of child2 
     </text> 
    </child2> 
    <text> 
     My Parent level text3 in <b> i am bold</b> 
    </text> 
</properties> 
Смежные вопросы