2010-08-23 3 views
3

Я громко рассмеялся, когда прочитал эту статью на Daily WTF: http://thedailywtf.com/Articles/WellFormed-XML.aspx, но теперь это уже не смешно, потому что я начал распознавать этот «шаблон шаблона xml» в дикой природе частота. например, я только что экспортировали некоторые данные из рационального запроса ClearQuest и я получил это:xsl transform для WTF «хорошо сформированный» пример

<?xml version="1.0" encoding="us-ascii"?> 
<?xml-stylesheet type="text/xsl" href="http://scm/rational/clearquest/webservice/resultset.xsl"?> 
<resultset dbset="CQMaster" dbname="PROD" entitydefname="TR" count="1" name="_my trs"> 
    <header count="3"> 
    <column type="dbid">dbid</column> 
    <column type="id">id</column> 
    <column type="short_string">Abstract</column> 
    </header> 
    <record> 
    <field>33607697</field> 
    <field>PROD00011111</field> 
    <field>The product has a bug that needs fixed.</field> 
    </record> 
</resultset> 

я не волшебник XSLT - я, наверное, понять это рано или поздно, но это не может повредить спросить ... что это самый простой шаблон XSLT для преобразования выше, в чем-то более полезным, как это:

<?xml version="1.0" encoding="us-ascii"?> 
<resultset dbset="CQMaster" dbname="PROD" entitydefname="TR" count="1" name="_my trs"> 
    <record> 
    <dbid type="dbid">33607697</dbid> 
    <id type="id">PROD00011111</id> 
    <Abstract type="short_string">The product has a bug that needs fixed.</Abstract> 
    </record> 
</resultset> 
+0

Хорошего вопрос (+1). См. Мой ответ для полного и короткого решения. :) –

ответ

1

следующее преобразование:

<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:key name="kColByPos" match="column" 
    use="count(preceding-sibling::*) +1"/> 

<xsl:template match="/*"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates select="record"/> 
    </xsl:copy> 
</xsl:template> 

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

<xsl:template match="field"> 
    <xsl:variable name="vColumn" select= 
    "key('kColByPos', position())"/> 

    <xsl:element name="{translate($vColumn, ' ', '_'}"> 
    <xsl:copy-of select="$vColumn/@type"/> 
    <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

при нанесении на предоставленном документе XML:

<resultset dbset="CQMaster" dbname="PROD" entitydefname="TR" count="1" name="_my trs"> 
    <header count="3"> 
    <column type="dbid">dbid</column> 
    <column type="id">id</column> 
    <column type="short_string">Abstract</column> 
    </header> 
    <record> 
    <field>33607697</field> 
    <field>PROD00011111</field> 
    <field>The product has a bug that needs fixed.</field> 
    </record> 
</resultset> 

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

<resultset dbset="CQMaster" dbname="PROD" entitydefname="TR" count="1" name="_my trs"> 
    <record> 
     <dbid type="dbid">33607697</dbid> 
     <id type="id">PROD00011111</id> 
     <Abstract type="short_string">The product has a bug that needs fixed.</Abstract> 
    </record> 
</resultset> 
+0

+1 для быстрого решения. он отлично работает, за исключением случаев, когда исходный xml имеет my type - пространство в имени столбца ломает результат. Я решил это, изменив ваш скрипт с помощью . спасибо за урок; Я никогда раньше не использовал xsl: key или position(). – rev

+0

@rev: О, я должен был подумать об этом сам (очень рассеянно сегодня ...). Ваше решение этой проблемы - именно то, что я сделал бы. Я отредактировал ответ и поместил исправление. –

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