xml - 使用 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>
解决方案
正如 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
希望能帮助到你。
推荐阅读
- multithreading - .NET CF WinCE 上的 EventArgs 线程是否安全
- android-studio - 无法创建以下文件,因为它已经存在。安卓工作室
- javascript - 带有 MariaDB 的 NodeJS,无法读取未定义的属性“threadId”
- gensim - 在 gensim 中使用向量进行相似性度量
- c++ - 一行中有多个“使用命名空间”?
- javascript - 无法访问 Dialogflow 实现参数
- ios - 捏动作有多少点移动?
- vue.js - 使用组件 url 参数访问 assets 文件夹
- f# - 默默减少失败
- r - 以非交互方式运行期望交互式输入的 R 包