我的输入 xml 如下所示
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<L1>
<L2>
<l3>
<item>
<State>1</state>
<currency>
<value1 xmlns:xs="www.anotherexample.com">5</value1>
<value2 xmlns:xs="www.anotherexample.com">dd</value2>
</currency>
</item>
<item2>
<a>1</a>
<b>2</b>
<c>3</c>
</item2>
<item3>
<e>2</e>
<l>3</l>
<m>3</m>
</item3>
<item4>
<n>r</n>
<p>5</p>
</item4>
</l3>
</L2>
</L1>
我有两个要求
1) xml 必须添加一个信封,即另一个 xml 将位于整个 xml 的顶部,结果应该看起来像
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<start>
<a></a>
.....
.....
<Body>
<Envelope>
<L1>
<L2>
<l3>
<item>
<State>1</state>
<currency>
<value1 xmlns:xs="www.anotherexample.com">5</value1>
<value2 xmlns:xs="www.anotherexample.com">ca</value2>
</currency>
</item>
<item2>
<a>1</a>
<b>2</b>
<c>3</c>
</item2>
<item3>
<e>2</e>
<l>3</l>
<m>3</m>
</item3>
<item4>
<n>r</n>
<p>5</p>
</item4>
</l3>
</L2>
</L1>
</Envelope>
</Body>
.....
.....
</start>
2 第二个要求是原始xml的根标签,即L1标签应该添加一个命名空间,这样根标签就变成
<start>
<a></a>
.....
.....
<Body>
<Envelope>
<L1 xmlns="www.example.com">
<L2>
<l3>
<item>
<State>1</state>
<currency>
<value1 xmlns:xs="www.anotherexample.com">5</value1>
<value2 xmlns:xs="www.anotherexample.com">ca</value2>
</currency>
</item>
<item2>
<a>1</a>
<c>3</c>
</item2>
<item3>
<e>2</e>
</item3>
<item4>
<n>r</n>
</item4>
</l3>
</L2>
</L1>
</Envelope>
</Body>
</start>
我们如何设计一个 xslt 来完成这种组合转换。我已经搜索并找到了将命名空间添加到根标记的解决方案,但是我如何同时实现这两个结果
注意:输入xml里面有很多元素会被调用模板忽略或处理,所以直接复制xml并添加命名空间在这种情况下会失败
示例:我可能只需要输出 xml 中输入的 1 个标签。编辑原始帖子以表明原始输入 xml 不打算按原样复制到输出,如新输出所示,输出 xml 将与输入 XML 不同,缺少几个标签和顺序标签必须是恒定的
抱歉之前的描述不完整
最佳答案
the second requirment is that the root tag of the original xml ie the L1 tag should have a namespace added to it
这不是您显示的输出内容的准确描述:全部 根的后代元素继承根的命名空间 - 因此您需要将新命名空间添加到每个元素中:
XSLT 1.0
<?xml version="1.0" encoding="UTF-8"?>
<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="*"/>
<xsl:template match="/">
<start>
<a></a>
<!-- ... -->
<Body>
<Envelope>
<xsl:apply-templates select="*" />
</Envelope>
</Body>
</start>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="www.example.com">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
当上述样式表应用于 时更正 输入:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<L1>
<L2>
<l3>
<item>
<state>1</state>
<currency>LEVEL</currency>
<value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
<value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
</item>
</l3>
</L2>
</L1>
结果是:
<?xml version="1.0" encoding="UTF-8"?>
<start>
<a/>
<Body>
<Envelope>
<L1 xmlns="www.example.com">
<L2>
<l3>
<item>
<state>1</state>
<currency>LEVEL</currency>
<value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
<value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
</item>
</l3>
</L2>
</L1>
</Envelope>
</Body>
</start>
编辑
如果您想删除 输出中的一些节点,为它们创建一个特定的模板并将其留空。例如,使用以下输入:
<L1>
<L2>
<l3>
<item>
<state>1</state>
<currency>
<value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
<value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
</currency>
</item>
<item2>
<a>1</a>
<b>2</b>
<c>3</c>
</item2>
<item3>
<e>2</e>
<l>3</l>
<m>3</m>
</item3>
<item4>
<n>r</n>
<p>5</p>
</item4>
</l3>
</L2>
</L1>
我们将为元素添加一个空模板
<b
, <l>
, <m>
和 <p>
到我们之前的样式表:<?xml version="1.0" encoding="UTF-8"?>
<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="*"/>
<xsl:template match="/">
<start>
<a></a>
<!-- ... -->
<Body>
<Envelope>
<xsl:apply-templates select="*" />
</Envelope>
</Body>
</start>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="www.example.com">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<xsl:template match="b|l|m|p"/>
</xsl:stylesheet>
并获得以下结果:
<?xml version="1.0" encoding="UTF-8"?>
<start>
<a/>
<Body>
<Envelope>
<L1 xmlns="www.example.com">
<L2>
<l3>
<item>
<state>1</state>
<currency>
<value1 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">5</value1>
<value2 xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:type="xs:int">ca</value2>
</currency>
</item>
<item2>
<a>1</a>
<c>3</c>
</item2>
<item3>
<e>2</e>
</item3>
<item4>
<n>r</n>
</item4>
</l3>
</L2>
</L1>
</Envelope>
</Body>
</start>
关于xml - 将命名空间添加到在其子项中具有命名空间的 xml,并通过 xslt 在其顶部添加新元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23479917/