我想对XML文件进行XSLT转换,确保将标记<B>
插入标记<A>
中,当且仅当它不存在时才会插入标记<A>foo</A> should become <A><B>foo</B></A>
<A>foo <x>bar</x></A> should become <A><B>foo <x>bar</x></B></A>
<A><B>foo</B></A> should remain <A><B>foo</B></A>
<A><B>foo <x>bar</x></B></A> should remain <A><B>foo <x>bar</x></B></A>
。例如:
<B>
因此<A>xxx <B>yyy</B></A> should become <A><B>xxx <B>yyy</B></B></A>
<A><B>xxx</B> yyy</A> should become <A><B><B>xxx</B> yyy</B></A>
应该插入,当且仅当它“缺失”时才会插入。
我该怎么做?
编辑(回应评论时的澄清):
<A>
即,<B>
应始终只有一个孩子,即==
,如果已满足此要求,则不应采取任何措施。
答案 0 :(得分:2)
我们可能需要根据您如何解决@ michael.hor257k指出的含糊不清情况进行调整,但这可以合理地解释您的要求:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="A[not(B)]">
<xsl:copy>
<B>
<xsl:apply-templates select="node()|@*"/>
</B>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
鉴于此输入XML:
<examples>
<A>foo</A>
<A>foo <x>bar</x></A>
<A><B>foo</B></A>
<A><B>foo <x>bar</x></B></A>
</examples>
它产生这个输出XML:
<examples>
<A><B>foo</B></A>
<A><B>foo <x>bar</x></B></A>
<A><B>foo</B></A>
<A><B>foo <x>bar</x></B></A>
</examples>
每次更新更新问题:
<A>
应该始终只有一个孩子,这是<B>
和。{ 如果已满足此要求,则不应采取任何措施。
好的,然后从
更改上面的模板匹配 <xsl:template match="A[not(B)]">
以强>
<xsl:template match="A[not(B) or count(node()) > 1]">
然后给出这个新的输入XML:
<examples>
<A>foo</A>
<A>foo <x>bar</x></A>
<A><B>foo</B></A>
<A><B>foo <x>bar</x></B></A>
<A>xxx <B>yyy</B></A>
<A><B>xxx</B> yyy</A>
</examples>
新的XSLT将生成这个新的输出XML
<examples>
<A><B>foo</B></A>
<A><B>foo <x>bar</x></B></A>
<A><B>foo</B></A>
<A><B>foo <x>bar</x></B></A>
<A><B>xxx <B>yyy</B></B></A>
<A><B><B>xxx</B> yyy</B></A>
</examples>
根据要求。
答案 1 :(得分:1)
<A>
应始终只有一个孩子,即<B>
然后你真的在寻找没有小孩节点的A
,或者有B
以外的子节点或者有多个B
个孩子:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="A[not(node()) or node()[not(self::B)] or count(B) > 1]">
<A>
<B>
<xsl:apply-templates select="@*|node()"/>
</B>
</A>
</xsl:template>
</xsl:stylesheet>
测试输入
<root>
<A/>
<A>foo</A>
<A>foo <x>bar</x></A>
<A><B>foo</B></A>
<A><B>foo <x>bar</x></B></A>
<A>xxx <B>yyy</B></A>
<A><B>xxx</B> yyy</A>
<A><B>foo</B><B>bar</B></A>
</root>
<强>结果强>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<A>
<B/>
</A>
<A>
<B>foo</B>
</A>
<A>
<B>foo <x>bar</x>
</B>
</A>
<A>
<B>foo</B>
</A>
<A>
<B>foo <x>bar</x>
</B>
</A>
<A>
<B>xxx <B>yyy</B>
</B>
</A>
<A>
<B>
<B>xxx</B> yyy</B>
</A>
<A>
<B>
<B>foo</B>
<B>bar</B>
</B>
</A>
</root>