2016-11-15 5 views
0

Я хотел бы объединить родительское значение атрибута с дочерним значением другого атрибута, а также удалить определенные атрибуты из XML-файла. Мой вход XML выглядит следующим образом:Объединить значения родительского и дочернего атрибутов xml с помощью xsl

<?xml version="1.0" encoding="UTF-8"?> 
<import_data> 
    <product part_number="12345" category="Parts and Accessories" description="Small-Part"> 
     <product_attribute name="organizationCode" value="XYZ"/> 
     <product_attribute name="Product Market" value="Rotors"/> 
     <product_attribute name="inventoryItemId" value="6789"> 
    </product> 
    <product part_number="ABCDE" category="Ball Bearings" description="Small-Part"> 
     <product_attribute name="organizationCode" value="XYZ"/> 
     <product_attribute name="Product Market" value="Rings"/> 
     <product_attribute name="inventoryItemId" value="FGHIJ"> 
    </product> 
</import_data> 

и результат должен выглядеть следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<import_data> 
    <product part_number="12345" category="Rotors.Parts and Accessories" description="Small-Part"> 
     <product_attribute name="Product Market" value="Rotors"/> 
    </product> 
    <product part_number="ABCDE" category="Rings.Ball Bearings" description="Small-Part"> 
     <product_attribute name="Product Market" value="Rings"/> 
    </product> 
</import_data> 

Мой XSL выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fo="http://www.w3.org/1999/XSL/Format" 
> 
<xsl:strip-space elements="*"/> 
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes"/> 

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


<xsl:template match="//so_product_attribute[@name='inventoryItemId']" /> 
<xsl:template match="//so_product_attribute[@name='organizationCode']" /> 

<xsl:template match="processing-instruction('xml-stylesheet')"/> 
</xsl:stylesheet> 

Я понял, как опускать нежелательные элементы (inventoryItemId и organizationCode), но я не могу понять, как читать значение дочернего элемента (product_attribute name = «Product Market» value = «Rotors») и объединить его со значением родительского атрибута (produ ct category = "Parts and Accessories"), чтобы он включал (категория продукта = «Роторы. Части и аксессуары»). Я экспериментировал с использованием xsl: for-each и считыванием значения дочернего элемента в переменную, но я не могу конкатенировать и выводить желаемое значение. Любая помощь будет принята с благодарностью.

ответ

1

Немного подправили свой XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fo="http://www.w3.org/1999/XSL/Format" 
    > 
    <xsl:strip-space elements="*"/> 
    <xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes"/> 

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

    <xsl:template match="product[normalize-space(product_attribute[@name = 'Product Market']/@value)]/@category"> 
    <xsl:attribute name="{name()}"> 
     <xsl:value-of select="concat(parent::product/product_attribute[@name = 'Product Market']/@value, '.', .)"/> 
    </xsl:attribute> 
    </xsl:template> 

    <xsl:template match="product_attribute[@name='inventoryItemId']" /> 
    <xsl:template match="product_attribute[@name='organizationCode']" /> 

    <xsl:template match="processing-instruction('xml-stylesheet')"/> 
</xsl:stylesheet> 
  • добавлен соответствующий шаблон для product/@category, если @value из product_attribute[@name = 'Product Market'] не является пустая строка. [это позволяет избежать точки перед категорией, если она отсутствует]
  • создать новый атрибут с тем же именем и конкатенировать @value с помощью . и содержимого контекстного узла (текущий атрибут).
  • изменено so_product_attribute, чтобы исправить имя элемента ввода
  • не начинаться с // в соответствии с шаблонами.
+0

спасибо. Был в состоянии реализовать ваши изменения, и он отлично работал. Кроме того, ваши заметки помогли мне понять причины вашего xsl. –

+0

Закрытие вопроса, помечая ответ как принятый, поможет мне и сообществу. Пожалуйста, примите все ответы на все ваши требования. – uL1

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