使用xsl

时间:2016-11-15 14:39:16

标签: xml xslt concatenation

我想将属性的父值与不同属性的子值连接起来,并从xml文件中删除特定属性。我的输入xml如下所示:

<?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和organizationalCode)但我无法弄清楚如何读取子元素的值(product_attribute name =&#34; Product Market&#34; value =&#34; Rotors&#34;)并将其与父属性(产品类别=&#34;零件和附件&#34;)属性的值相结合,以便它组合成(产品类别=& #34; Rotors.Parts and Accessories&#34;)。我已经尝试使用xsl:for-each并将子值读入变量但我无法连接并输出所需的值。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分: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的{​​{1}}是非空字符串。 [这样可以避免在类别前面出现一个点,如果没有的话]
  • 创建具有相同名称的新属性,并使用product_attribute[@name = 'Product Market']连接@value以及context-node(当前属性)的内容。
  • .更改为更正输入元素的名称
  • 不要以匹配模式中的so_product_attribute开头。