在XSLT中定义编码

时间:2016-05-01 12:58:14

标签: xml xslt

下面转换的源XML文档可能是这样的(反向工程并由Dimitre提供):

<Provider Identifier="1P">
  <Identifications>
    <Identification>
     <Value>1013977438</Value>
     <Type>Z86</Type>
    </Identification>
    <Identification>
     <Value>1013977438</Value>
     <Type>HPI</Type>
    </Identification>
    <Identification>
     <Type>HPI</Type>
    </Identification>
  </Identifications>
</Provider>

我的XSLT代码是:

<xsl:template match="Identifications">
    <xsl:if test="/Provider/Identifications/Identification/Value!=''">
        <Identifications>
            <xsl:for-each select="/Provider/Identifications/*">
                <Identification>
                    <xsl:for-each select="*">
                        <xsl:attribute name="{name()}">
                            <xsl:value-of select="text()"/>
                        </xsl:attribute>
                    </xsl:for-each>
                </Identification>
            </xsl:for-each>
        </Identifications>
    </xsl:if>
</xsl:template>

但我的愿望输出是:

<Provider Identifier="1P">
  <Identifications>
    <Identification Value="1013977438" Type="Z86"/>
    <Identification Value="1013977438" Type="HPI"/>
  </Identifications>
</Provider>

现在我应该在上面的XSLT中应用什么条件?

3 个答案:

答案 0 :(得分:3)

所有提供的答案都不必要地复杂。

只需使用

<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:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="Identification[not(@Value)]"/>
</xsl:stylesheet>

<强>更新

最初我认为OP提供了他的源XML文档。现在我看到这实际上是他转型的结果

我不得不对实际的源XML可能是进行逆向工程。像这样:

<Provider Identifier="1P">
  <Identifications>
    <Identification>
     <Value>1013977438</Value>
     <Type>Z86</Type>
    </Identification>
    <Identification>
     <Value>1013977438</Value>
     <Type>HPI</Type>
    </Identification>
    <Identification>
     <Type>HPI</Type>
    </Identification>
  </Identifications>
</Provider>

同样,有一个比其他答案提供的更简单的解决方案:

<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:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Identification[Value]/*">
    <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
  </xsl:template>
  <xsl:template match="Identification[not(Value)]"/>
</xsl:stylesheet>

答案 1 :(得分:2)

你的方法不是真正的最简单的方法。您可以尝试将模板更改为以下内容:

<xsl:template match="Identifications">
        <Identifications>
                 <xsl:apply-templates select="*[./Value!='']"/>
        </Identifications>
</xsl:template>

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

答案 2 :(得分:0)

尝试这样的事情:

  • 从身份转换开始
  • 具有值属性标识的模板不为空 <xsl:template match="Identification[@Value!='']">
  • 一个忽略所有其他身份证明的模板 <xsl:template match="Identification" />

因此:

 <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">      

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

  <xsl:template match="Identification[@Value!='']">
        <Identification>
          <xsl:apply-templates select="@*|node()"/>
        </Identification>
  </xsl:template>

  <xsl:template match="Identification" />

</xsl:stylesheet>