2015-03-04 5 views
0

Я новичок, когда речь заходит о переводах XSLT, и некоторое время искал этот вопрос, но не нашел ответа на него. У меня есть XML-файл вид:Перемещение и переименование содержимого узла XML

<item> 
    <code>I001</code> 
    <description>DEF</description> 
    <properties> 
    <line1> 
     <key>key 1</key> 
     <value>value 1</value> 
    </line1> 
    <line2> 
     <key>key 2</key> 
     <value>value 2</value> 
    </line2> 
    </properties> 
</item> 

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

<?xml version="1.0" encoding="utf-8"?> 
<item> 
    <code>I001</code> 
    <description>DEF</description> 
    <P1_key>key 1</P1_key> 
    <P1_value>value 1</P1_value> 
    <P2_key>key 1</P2_key> 
    <P2_value>value</P2_value> 
</item> 

до сих пор я придумал с XSL-файл, который выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 
    <xsl:output method="xml" indent="yes"/> 

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

    <!-- special rules ... --> 
    <xsl:template match="properties/line1/*"> 
    <xsl:element name="P1_{local-name()}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 
    <xsl:template match="properties/line2/*"> 
    <xsl:element name="P2_{local-name()}"> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

Это делает только отчасти то, что мне нужно (переименование элементов), остроумие результат вида:

<?xml version="1.0" encoding="utf-8"?> 
<item> 
    <code>I001</code> 
    <description>DEF</description> 
    <properties> 
    <line1> 
     <P1_key>key 1</P1_key> 
     <P1_value>value 1</P1_value> 
    </line1> 
    <line2> 
     <P2_key>key 1</P2_key> 
     <P2_value>value</P2_value> 
    </line2> 
    </properties> 
</item> 

Что я теперь хотел бы сейчас, как переместить переименованные элементы (P1_key, P1_value, P2_key, P2_value) до уровня.

Любые советы были бы оценены.

Благодаря

ответ

1

Как насчет:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> 

<xsl:template match="/item"> 
    <xsl:copy> 
     <xsl:copy-of select="code | description"/> 
     <xsl:for-each select="properties/*/key"> 
      <xsl:element name="P{position()}_key"> 
       <xsl:value-of select="."/> 
      </xsl:element> 
      <xsl:element name="P{position()}_value"> 
       <xsl:value-of select="following-sibling::value[1]"/> 
      </xsl:element> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

Или возможно:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> 

<xsl:template match="/item"> 
    <xsl:copy> 
     <xsl:copy-of select="code | description"/> 
     <xsl:for-each select="properties/*/key"> 
     <xsl:variable name="line-num" select="substring-after(name(..), 'line')" /> 
      <xsl:element name="P{$line-num}_key"> 
       <xsl:value-of select="."/> 
      </xsl:element> 
      <xsl:element name="P{$line-num}_value"> 
       <xsl:value-of select="following-sibling::value[1]"/> 
      </xsl:element> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

Конечно, если всегда будет ровно две строки, вы мог бы просто указать:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> 

<xsl:template match="/item"> 
    <xsl:copy> 
     <xsl:copy-of select="code | description"/> 
     <P1_key> 
      <xsl:value-of select="properties/line1/key" /> 
     </P1_key> 
     <P1_value> 
      <xsl:value-of select="properties/line1/value" /> 
     </P1_value> 
     <P2_key> 
      <xsl:value-of select="properties/line2/key" /> 
     </P2_key> 
     <P2_value> 
      <xsl:value-of select="properties/line2/value" /> 
     </P2_value> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

BTW, ваш метод может работать также, если добавить еще один шаблон:

<xsl:template match="properties | line1 | line2"> 
    <xsl:apply-templates /> 
</xsl:template> 
+0

Привет, спасибо за ваши предложения. Поскольку реальный XML, который я хочу преобразовать, несколько сложнее, чем мой пример, я думаю, что пойду со вторым предложением. В то же время у меня появилась возможность записать все, но это оставило меня с XSLT-файлом в 53 КБ! Еще раз спасибо! –

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