gpt4 book ai didi

xml - 处理 XML 和 XSLT 中默认命名空间的最佳解决方案

转载 作者:数据小太阳 更新时间:2023-10-29 01:48:29 24 4
gpt4 key购买 nike

如果您在输入 XML 中有一个默认 namespace ,并且在要完成的 XSLT 转换中您只想在该 namespace 中添加一个元素,你们会怎么做?

您是否也将命名空间声明为 XSLT 中的默认命名空间?还是您在 XSLT 中使用前缀,并在 XSLT 中将所有元素放入该 namespace ?

我创建了 5 个选项,其中一个选项是错误的,所有其他 4 个都给出了正确的结果,但我只是想知道哪种方式最好,或者是否有更好的方式?

我使用下一个 XML 作为所有示例的输入:

<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="http://example.org/uri/">
<element attr="test">
<one>This is an example</one>
<two>Pretty nice</two>
</element>
</data>

选项 1、2 和 3

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pref="http://example.org/uri/" exclude-result-prefixes="pref">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>

<xsl:template match="pref:element">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>

<added>Option 1</added>
<xsl:element name="added" namespace="http://example.org/uri/">Option 2</xsl:element>
<added xmlns="http://example.org/uri/">Option 3</added>
</xsl:template>
</xsl:stylesheet>

将产生:

<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="http://example.org/uri/">
<element attr="test">
<one>This is an example</one>
<two>Pretty nice</two>
</element>
<added xmlns="">Option 1</added>
<added>Option 2</added>
<added>Option 3</added>
</data>

从上面的选项 1 不会创建正确的输出,因为没有在任何地方声明默认命名空间。选项 2 和 3 将创建正确的输出,但如果我要添加多个元素,则 XSLT 看起来不太好,因为我需要在所有元素上添加 namespace 。

看到上面你会说:我将在 XSLT 中添加一个默认 namespace ,就像我在选项 4 中所做的那样。

选项 4

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://example.org/uri/" xmlns:pref="http://example.org/uri/" exclude-result-prefixes="pref">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>

<xsl:template match="pref:element">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>

<added>Option 4</added>
</xsl:template>
</xsl:stylesheet>

这将产生:

<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="http://example.org/uri/">
<element attr="test">
<one>This is an example</one>
<two>Pretty nice</two>
</element>
<added>Option 4</added>
</data>

XSLT 看起来更好,因为我不必在添加到 XML 的每个元素上声明 namespace 。不知道为什么我应该或不应该这样做?当输入 XML 可能有 2 个不同的默认 namespace 时,我可能会遇到问题吗?所以有时我们会在命名空间 xmlns="http://example.org/uri/" 中接收它,有时在命名空间 xmlns="http://example.org/uriSecond/"中接收它

选项 5

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pref="http://example.org/uri/" exclude-result-prefixes="pref">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>

<xsl:template match="pref:*">
<xsl:element name="pref:{local-name()}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>
</xsl:template>

<xsl:template match="pref:element">
<xsl:element name="pref:{local-name()}">
<xsl:apply-templates select="@*|node()" />
</xsl:element>

<pref:added>Option 5</pref:added>
</xsl:template>
</xsl:stylesheet>

将产生:

<?xml version="1.0" encoding="UTF-8"?>
<pref:data xmlns:pref="http://example.org/uri/">
<pref:element attr="test">
<pref:one>This is an example</pref:one>
<pref:two>Pretty nice</pref:two>
</pref:element><pref:added>Option 5</pref:added>
</pref:data>

也是一个正确的结果,所有元素都被重写到一个带前缀的命名空间中。 XSLT 中也没有声明默认 namespace 。如果我现在要接收具有不同默认命名空间的第二个输入,我也可以声明它并复制所有具有该前缀的 pref: 模板。

所以我真的在寻找最好的解决方案,这样我以后就不会遇到任何麻烦了。还是所有可行的解决方案都是一种好方法,但要根据问题选择您的路径?

最佳答案

我认为选项 4 最清楚。

如果您必须在不同模板的不同默认命名空间中添加节点,那么您可以在 3 到 4 之间选择一些东西,并在每个模板上放置一个 xmlns="...":

<xsl:template match="ns1:something" xmlns="urn:ns1">
<element1 />
<element2 />
</xsl:template>

但是您的最后一段总结得很好 - 了解所有选项并在每种情况下使用最有意义的选项。

关于xml - 处理 XML 和 XSLT 中默认命名空间的最佳解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20090833/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com