使用XSL转换XML(具有嵌套标记)

时间:2016-05-25 15:48:08

标签: xml xslt

我有一个类似......的XML

<?xml version='1.0' encoding='utf-8'?>
<HL7Message>
    <MSH>
        <MSH.1>|</MSH.1>
        <MSH.2>^~\&amp;</MSH.2>
        <MSH.3>
            <MSH.3.1>ST01</MSH.3.1>
        </MSH.3>
        <MSH.4>
            <MSH.4.1>A</MSH.4.1>
        </MSH.4>
        <MSH.5>
            <MSH.5.1>HC</MSH.5.1>
            <MSH.5.2>HC2</MSH.5.2>
        </MSH.5>
    </MSH>
</HL7Message>

我希望将其转换为以下格式,以便solr可以接受它。

<add>
<doc>
  <field name="MSH.1">|</field>
  <field name="MSH.2">^~\&amp;</field>
  <field name="MSH.3.1">ST01</field>
  <field name="MSH.4.1">A</field>
  <field name="MSH.5.1">HC</field>
  <field name="MSH.5.2">HC2</field>
</doc>
</add>

现在我已经创建了一个XSLT,如下所示..

<?xml version='1.0' encoding='utf-8'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output method="xml" encoding="utf-8" indent="yes"/> 
<xsl:strip-space elements="*" />
<xsl:template match="MSH">
<add><doc>
<xsl:apply-templates select="MSH"/>
<xsl:for-each select="*">
<xsl:element name="field">

<xsl:attribute name="name"><xsl:value-of select="node()"/</xsl:attribute>
<xsl:value-of select="."/>
</xsl:element>

</xsl:for-each>
</doc></add>
</xsl:template>
</xsl:stylesheet>

但现在转换为以下格式..

<add>
<doc>
  <field name="MSH.1">|</field>
  <field name="MSH.2">^~\&amp;</field>
  <field name="MSH.3">ST01</field>
  <field name="MSH.4">A</field>
  ***<field name="MSH.5">HCHC2</field>***
</doc>
</add>

我们可以看到MSH 5.1和MSH 5.2正在结合,这是我期待的......

如果有人可以帮助或指导我在哪里犯错误,我将不胜感激。提前致谢。

1 个答案:

答案 0 :(得分:1)

您应该选择任何自身没有子元素的后代元素,而不是只选择MSH元素的直接子元素。

<xsl:for-each select=".//*[not(*)]">

因此,这会选择MSH.5.1MSH.5.2,但不会选择MSH.5本身。

尝试使用此XSLT(我还使用属性值模板进行了简化,以创建@name属性)

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

<xsl:template match="MSH">
  <add>
  <doc>
    <xsl:for-each select=".//*[not(*)]">
      <field name="{name()}">  
        <xsl:value-of select="."/>
      </field>
    </xsl:for-each>
  </doc>
  </add>
</xsl:template>
</xsl:stylesheet>