我有一个新的要求,要使转换的XML更具可读性,即保留元素之间的cr,制表符和其他空格。
我似乎无法弄清楚如何保留空白。
有人可以帮忙吗?
XML文件
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
</Fragment>
</Wix>
XSL文件:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:m="http://schemas.microsoft.com/wix/2006/wi">
<xsl:preserve-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/m:Wix">
<xsl:message>Matched Wix</xsl:message>
<xsl:copy>
<!-- Insert the new include processing instruction -->
<xsl:processing-instruction name="include">
<xsl:text>$(sys.CURRENTDIR)src/includes/globals.wxi </xsl:text>
</xsl:processing-instruction>
<!-- place the existing children into the output -->
<xsl:apply-templates select="@* | *"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当前输出:
<?xml version="1.0" encoding="UTF-8"?><Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"><?include $(sys.CURRENTDIR)src/includes\globals.wxi ?><Fragment>
</Fragment></Wix>
期望输出:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include $(sys.CURRENTDIR)src/includes\globals.wxi ?>
<Fragment>
</Fragment>
</Wix>
答案 0 :(得分:1)
通过在流程指令之前和之后添加以下文本,考虑使用换行符

和制表符实体	
。并确保将缩进输出标题添加到顶部:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:m="http://schemas.microsoft.com/wix/2006/wi">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:preserve-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/m:Wix">
<xsl:message>Matched Wix</xsl:message>
<xsl:copy>
<xsl:text>
 	</xsl:text>
<!-- Insert the new include processing instruction -->
<xsl:processing-instruction name="include">
<xsl:text>$(sys.CURRENTDIR)src/includes/globals.wxi </xsl:text>
</xsl:processing-instruction>
<xsl:text>
 	</xsl:text>
<!-- place the existing children into the output -->
<xsl:apply-templates select="@* | *"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
或者,使用多个非中断空格实体 
代替制表符,以便更精确地对齐:
<xsl:text>
    </xsl:text>
<强>输出强>
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include $(sys.CURRENTDIR)src/includes/globals.wxi?>
<Fragment>
</Fragment>
</Wix>
答案 1 :(得分:1)
输入中有三个空白文本节点:两个是Fragment元素的兄弟节点,另一个是Fragment元素的子节点。
前两个没有被复制到你的输出,因为m:Wix元素的模板忽略了它们:<xsl:apply-templates select="@* | *"/>
只选择元素子元素,而不是文本节点子元素。
处理Fragment的空白文本内容,并保留在输出中。
现在:你在问题中说两件事:(a)你想让输出可读,(b)你想保留输入中的空白。我建议(b)不是实现(a)的最佳方式。实现(a)的最佳方法是忽略输入中存在的空白,并使用xsl:output indent="yes"
在输出中添加新的空格。
但是,如果您确实要将输入中的空格复制到输出,则在处理元素的子元素时需要使用select="node()"
而不是select="*"
。
答案 2 :(得分:0)
我的漂亮打印选择工具是xmlint。
xmllint --format old.xml > new.xml
但我确实看到你正在添加处理指令。所以需要xslt。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:m="http://schemas.microsoft.com/wix/2006/wi"
exclude-result-prefixes="m">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:preserve-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="m:Wix">
<xsl:message>Matched Wix</xsl:message>
<Wix>
<xsl:call-template name="CR"/>
<xsl:call-template name="TAB"/>
<!-- Insert the new include processing instruction -->
<xsl:processing-instruction name="include">
<xsl:text>$(sys.CURRENTDIR)src/includes/globals.wxi</xsl:text>
</xsl:processing-instruction>
<!-- place the existing children into the output -->
<xsl:apply-templates/>
</Wix>
</xsl:template>
<xsl:template match="m:Fragment">
<Fragment>
<xsl:apply-templates/>
</Fragment>
</xsl:template>
<xsl:template name="CR">
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="TAB">
<xsl:text>	</xsl:text>
</xsl:template>
</xsl:stylesheet>
如果您的真实XML变得更复杂,您可能需要先xmllint。然后做一个简单的xslt来添加处理指令。 Xmllint非常容易识别空格,xslt你必须把它烘烤。