2009-03-17 6 views
17

У нас есть текущая система, которая выводит файл XML, который находится в следующем формате:Преобразование XML-элементов в XML-атрибутов с помощью XSLT

<INVENTORY> 
    <ITEM> 
     <SERIALNUMBER>something</SERIALNUMBER> 
     <LOCATION>something</LOCATION> 
     <BARCODE>something</BARCODE> 
    </ITEM> 
</INVENTORY> 

мне нужно использовать эти данные для загрузки в стандартный .NET 2.0 сетки , Но сетка нуждается в XML, чтобы быть в следующем формате:

<INVENTORY> 
    <ITEM serialNumber="something" location="something" barcode="something"> 
    </ITEM> 
</INVENTORY> 

т.е. дочерние узлы элемента должны быть преобразованы в атрибуты узла элемента.

Кто-нибудь знает, как это можно сделать с помощью XSLT?

+0

Прочитайте документацию по разметке, вам нужно 4 пробела или вкладку, чтобы SO распознал код. – AnthonyWJones

+0

Ответ, который вы приняли, не дает желаемого результата! Одно имя атрибута должно быть «serialNumber», принятое решение создает «serialnumber». В следующий раз не вводите в заблуждение людей, которые проводят время, чтобы помочь. –

ответ

27

Это должно работать:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="INVENTORY"> 
    <INVENTORY> 
     <xsl:apply-templates/> 
    </INVENTORY> 
    </xsl:template> 

    <xsl:template match="ITEM"> 
    <ITEM> 
     <xsl:for-each select="*"> 
     <xsl:attribute name="{name()}"> 
      <xsl:value-of select="text()"/> 
     </xsl:attribute> 

     </xsl:for-each> 
    </ITEM> 
    </xsl:template> 
</xsl:stylesheet> 

НТН

+0

Спасибо за все ваши предложения, но это похоже на самое простое и динамичное решение :) и работал для меня :) – eMTeeN

2

Это должно сделать это:

<xsl:for-each select="//ITEM"> 
    <xsl:element name="ITEM"> 
     <xsl:attribute name="serialNumber"> 
     <xsl:value-of select="SERIALNUMBER"/> 
     </xsl:attribute> 
     <xsl:attribute name="location"> 
     <xsl:value-of select="LOCATION"/> 
     </xsl:attribute> 
     <xsl:attribute name="barcode"> 
     <xsl:value-of select="BARCODE"/> 
     </xsl:attribute> 
    </xsl:element> 
    </xsl:for-each> 

Или используя ярлык Давида:

<xsl:for-each select="//ITEM"> 
    <ITEM serialNumber="{SERIALNUMBER}" location="{LOCATION}" barcode="{BARCODE}"/> 
</xsl:for-each> 
2

Если ваш источник выглядит следующим образом:

<row><a>1</a><b>2</b></row> 

и вы хотите, чтобы выглядеть это:

<row a="1" b="2" /> 

этот XSLT должен работать:

<xsl:template match="row"> 
    <row a="{a}" b="{b}" /> 
</xsl:template> 
4

Эти два шаблона должны сделать это: -

<xsl:template match="ITEM"> 
    <ITEM serialNumber="{SERIALNUMBER}" location="{LOCATION}" barcode="{BARCODE}" /> 
</xsl:template> 

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

Здесь вероятно, самые простые soluti на, который будет конвертировать любые дети-элементы ITEM к его атрибутам и будет воспроизводить все остальное, как есть, в то время как преобразование имен элементов в любых желаемых имен атрибутов:

<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:variable name="vrtfNameMapping"> 
    <item name="SERIALNUMBER" newName="serialNumber"/> 
    <item name="LOCATION" newName="location"/> 
    <item name="BARCODE" newName="barcode"/> 
    </xsl:variable> 
<!--            --> 
    <xsl:variable name="vNameMapping" select= 
    "document('')/*/xsl:variable[@name='vrtfNameMapping']"/> 
<!--            --> 

    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
    </xsl:template> 
<!--            --> 
    <xsl:template match="ITEM/*"> 
    <xsl:attribute name= 
    "{$vNameMapping/*[@name=name(current())]/@newName}"> 
     <xsl:value-of select="."/> 
    </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

когда выше преобразование применяется на условии XML документ:

<INVENTORY> 
    <ITEM> 
     <SERIALNUMBER>something</SERIALNUMBER> 
     <LOCATION>something</LOCATION> 
     <BARCODE>something</BARCODE> 
    </ITEM> 
</INVENTORY> 

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

<INVENTORY> 
    <ITEM serialNumber="something" location="something" barcode="something"/> 
</INVENTORY> 

Обратите внимание следующее:

  1. Использование в identity rule

  2. Использование <xsl:strip-space elements="*"/>

  3. Использование переменной vrtfNameMapping без функции xxx:node-set() расширения ,

  4. Тот факт, что мы обрабатываем любое сопоставление между именем и новым именем, а не только простой нижний кожух.

+0

Не похоже, что это преобразование работает. Это не дает никакого результата. Просто так: Mark

+0

@Mark, Это означает, что вы либо процессор глючит XSLT, или вы не скопировали и вставили точно XML-документ и преобразование. Я просто повторно выполнил преобразование - тот же результат получается с несколькими XSLT-процессорами –

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