xml - 如果 XML 中没有标签,如何在使用 XSLT 转换为 CSV 时添加名称?
问题描述
我有两种情况,当我必须处理 XML 并使用 XSLT 创建 CSV 时,我无法继续前进。输入文件:
<?xml version="1.0" encoding="utf-8"?>
<families>
<family id ="1">
<type_client>
<code>1</code>
<code>2</code>
</type_client>
<family_client>
<code>99</code>
<code>98</code>
</family_client>
</family>
<family id ="2">
<type_client>
<code>3</code>
<code>4</code>
</type_client>
<family_client>
<code>88</code>
<code>89</code>
</family_client>
</family>
</families>
场景 1:在将 XML 文件转换为 CSV 时,无论标签是否存在,我都必须添加标签名称“ family_name ”(即,如果标签存在,标签名称应该出现,否则自定义名称应该出现)。如果标签存在,local-name() 将给出名称,否则不会给出。如果标签不存在,如何添加标签名称?
场景 2:<type_client>
有重复的子标签,即<code>99</code>
和<code>98</code>
(来自示例)。我必须添加与此标签一样多的记录,<code>
即,从示例中我必须添加 2 条记录。两种方案的预期输出:
type_client.csv
id,family_name,type_client
1,,1
1,,2
2,,3
2,,4
family_client.csv
id,family_name,family_client
1,,99
1,,98
2,,88
2,,89
XSLT:
<xsl:stylesheet xmlns:xsl="w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" method="text"/>
<xsl:template match="families">
<xsl:result-document href="type.txt">
<xsl:value-of select="family[1]/@id/local-name(),family[1]/family_name/local-name(),family[1]/type_client/local-name()" separator=","/>
<xsl:text>
</xsl:text>
<xsl:for-each select="family">
<xsl:value-of select="@id,family_name,type_client/code" separator=","/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
下面是我得到的输出:
id,family_name,type_client
1,Husband's Family,1,2
2,Wife's Family,3,4
注意:这里family_name
的值是手动添加的,以显示如果它有数据应该如何出现,否则在阅读评论后,当标签不存在时,标签作为名称应该出现。
预期输出:
id,family_name,type_client
1,Husband's Family,1
1,Husband's Family,2
2,Wife's Family,3
2,Wife's Family,4
解决方案
family_name
如果不存在,我不认为这是添加的情况。如果值不存在,则确保在 CSV 中输出值。
而不是这样做...
<xsl:value-of select="@id,family_name,type_client/code" separator=","/>
你可以这样做(||
连接运算符在哪里)
<xsl:value-of select="@id,(family_name||''),type_client/code" separator=","/>
所以如果不存在(family_name||'')
则返回一个空字符串。family_name
如果family_name
确实存在,则连接一个空字符串不会影响它。
标题行的创建似乎有点过于复杂。而不是这样做......
<xsl:value-of select="family[1]/@id/local-name(),family[1]/family_name/local-name(),family[1]/type_client/local-name()" separator=","/>
您可以这样做,因为local-name()
当您已经知道名称是什么时使用没有意义(因为您已在 xpath 表达式中对其进行硬编码)
<xsl:text>id,family_name,type_client</xsl:text>
对于您的方案 2,解决方案是使用xsl:for-each
而不family/type_client/code
只是家庭
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" method="text"/>
<xsl:template match="families">
<xsl:result-document href="type.txt">
<xsl:text>id,family_name,type_client
</xsl:text>
<xsl:for-each select="family/type_client/code">
<xsl:value-of select="../../@id,(../family_name||''),." separator=","/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- powershell - 如何将主文件夹和 Active Directory 与复制/删除文件夹进行比较?
- android - 清洁架构中具有多个响应列表的用例
- typescript - 测试涉及打开文件夹/工作区的 VSCode 扩展
- bootstrap-4 - 屏幕分辨率小于 576px 的 boostrap-grid 中的 react-slick
- azure - 找不到如何加载包含 Get-MsolUser 的库
- c - 如何为此方法格式化字符串?
- javascript - 对象数组中特定对象的修剪属性
- reactjs - 如何在 React 应用程序中将 JWPlayer 或 Plyr.io 用于视频播放器?
- xamarin - ExtraScanOverlayLayoutId CardIOActivity 选项中可以接受哪些值?
- angular - 当测试成功完成后没有当前规范时使用“期望”