首页 > 解决方案 > 使用 XSLT 将 XML 中的标记转换为另一种格式无法正常工作

问题描述

我正在尝试编写一个能够将 XML 转换为具有所需格式的另一个 XML 的样式表。

原始 XML 具有以下代码:

    <Header>
        <owner>Person</owner>
        <version>1</version>
        <type>C</type>
        <publishTime>2018-07-11T10:27:15.917+01:00</publishTime>
        <ns2:Infos>
            <ns2:Info>
                <key>Context</key>
                <value>23276</value>
            </ns2:Info>
        </ns2:Infos>
    </Header>
    <payload id="APOL3001">
        <concept id="IMPOST" value="27,33"/>
        <concept id="RISCOS">
            <concept id="1">
                <concept id="CODRIS" value="101"/>
                <concept id="DESRIS" value="stuff"/>
                <concept id="VALFRQ" value="0"/>
                <concept id="INDFRQ" value="0"/>
                <concept id="DIAFRQ" value="000"/>
                <concept id="CAPTAL" value="117.755,82"/>
                <concept id="ZFMIN" value="000000000"/>
                <concept id="CAPFRQ" value="0%"/>
            </concept>
        </concept>
    </payload>
</iDocMessage>

所需的输出是获取 ids 和 values 并使它们成为标签和这些标签的值,为此我编写了以下样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>
    
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="concept">
    <xsl:element name="{@id}">
      <xsl:value-of select="@value"/>
    </xsl:element>
  </xsl:template>
  
  <xsl:template match="payload">
      <xsl:element name="{@id}">
          <xsl:value-of select="@value"/>
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

问题是它正在输出以下 XML:

<?xml version="1.0" encoding="utf-16"?>
<iDocMessage xmlns:ns2="http://imessage.com/ws/core">
  <Header>
    <owner>Person</owner>
    <version>1</version>
    <type>C</type>
    <publishTime>2018-07-11T10:27:15.917+01:00</publishTime>
    <ns2:Infos>
      <ns2:Info>
        <key>Context</key>
        <value>23276</value>
      </ns2:Info>
    </ns2:Infos>
  </Header>
  <APOL3001></APOL3001>
</iDocMessage>

如您所见,它在转换概念标签时忽略了缩进甚至不显示标签。即使我删除了有效负载转换,它也只显示前 2 个概念标签已转换。我错过了什么?

另外,我怎样才能使它<root> and <DOC>在 XML 的开头和结尾添加一个标签?

您可以在以下链接中看到我在操作中展示的元素:https ://xsltfiddle.liberty-development.net/gVrvcxc/2

编辑:

所需的输出将是:

<?xml version="1.0" encoding="utf-16"?>
<iDocMessage xmlns:ns2="http://imessage.com/ws/core">
  <Header>
    <owner>Person</owner>
    <version>1</version>
    <type>C</type>
    <publishTime>2018-07-11T10:27:15.917+01:00</publishTime>
    <ns2:Infos>
      <ns2:Info>
        <key>Context</key>
        <value>23276</value>
      </ns2:Info>
    </ns2:Infos>
  </Header>
  <APOL3001></APOL3001>
    <IMPOST>27,33</IMPOST>
    <RISCOS>
      <1>
        <CODRIS>101</CODRIS>
        <DESRIS>stuff</DESRIS>
        ...
      </1>
    </RISCOS>
  </APOL3001>
</iDocMessage>

标签: xmlxslt

解决方案


正如 Martin 所说,它可以像下面这样格式化以获得预期的输出:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

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

<xsl:template match="/">
    <root>
        <xsl:apply-templates select="*"/>
    </root>
</xsl:template>

<xsl:template match="concept">
    <xsl:choose>
        <xsl:when test="string(number(@id)) != 'NaN'">
            <xsl:element name="{concat('Number_',@id)}">
                <xsl:value-of select="@value"/>
                <xsl:apply-templates />
            </xsl:element>
        </xsl:when>
        <xsl:otherwise>
            <xsl:element name="{@id}">
                <xsl:value-of select="@value"/>
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="payload">
    <xsl:element name="{@id}">
        <xsl:value-of select="@value"/>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/aiyne2

希望能帮助到你。


推荐阅读