我想要一个XML样式表(XSLT),它将一些特定的子节点的属性放在一行。什么是XSLT?
我最近问过related question有人提供样式表来解决,但是他们的样式表由于某种原因不起作用,我很好奇为什么 - 这些属性根本不是每行一行
举例来说,我的XML可能如下所示:
<MyXML>
<NodeA>
<ChildNode value1='5' value2='6' />
</NodeA>
<NodeB>
<AnotherChildNode value1='5' value2='6' />
</NodeB>
<NodeC>
<AnotherChildNode value1='5' value2='6' />
</NodeC>
</MyXML>
我想要一个样式表,它将扩展所有NodeA和NodeB但不是NodeC,并使它看起来像这样:
<MyXML>
<NodeA>
<ChildNode
value1='5'
value2='6' />
</NodeA>
<NodeB>
<AnotherChildNode
value1='5'
value2='6' />
</NodeB>
<NodeC>
<AnotherChildNode value1='5' value2='6' />
</NodeC>
</MyXML>
答案 0 :(得分:1)
我认为XSLT不适合这项工作。
XSLTs的目标是将数据从一种格式转换为另一种格式。
你可以实现输出“漂亮印刷”的换行符,但你应该记住,这总是一种“黑客”。
是否有理由使用XSLT而不是$ PreferedScriptingLanguage?
答案 1 :(得分:1)
XML明智的,这些是完全相同的。因此,使用XSLT转换它们不会改变它们。
所以你可能会尝试
滥用某些XSLT处理器(带有身份XSLT转换)作为“漂亮”的打印机。
获取或编写一个特别漂亮的打印机。
保持XML原样,并调整处理链中的下一步以解析XML,而不是在行上解析值。
我赞成3。
答案 2 :(得分:1)
嗯...如果(且仅当)输入XML已经正确缩进,您可以放弃:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output encoding="utf-8" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="NodeA/*|NodeB/*">
<xsl:variable name="spc" select="preceding-sibling::text()[1]" />
<xsl:value-of select="concat('<', name())" disable-output-escaping="yes" />
<xsl:for-each select="@*">
<xsl:value-of select="concat($spc, ' ', name(), '="', ., '"')" />
</xsl:for-each>
<xsl:choose>
<xsl:when test="node()">
<xsl:value-of select="'>'" disable-output-escaping="yes" />
<xsl:apply-templates select="node()" />
<xsl:value-of select="concat('</', name(), '>')" disable-output-escaping="yes" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="' />'" disable-output-escaping="yes" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
但说实话,我认为这正是@echox谈论的丑陋黑客。
以上输出为:
<MyXML>
<NodeA>
<ChildNode
value1="5"
value2="6" />
</NodeA>
<NodeB>
<AnotherChildNode
value1="5"
value2="6" />
</NodeB>
<NodeC>
<AnotherChildNode value1="5" value2="6"></AnotherChildNode>
</NodeC>
</MyXML>