默认转换器和 XSLT 身份转换的不同行为

问题描述 投票:0回答:1

我有以下 XML:

<?xml version="1.0"?>
<x:books xmlns:x="urn:collection" xmlns:p="urn:property">
  <book id="bk001">
    <p:author>Writer</p:author>
    <p:title>The First Book</p:title>
    <p:genre>Fiction</p:genre>
  </book>
</x:books>

它是用不知道名称空间的解析器解析的:

DocumentBuilderFactory factory = DocumentBuilderFactory.newDefaultInstance(); // JDK-default implementation
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(new InputSource(new StringReader(xmlString)));

当使用默认身份转换器将其转换回字符串时...

TransformerFactory factory = TransformerFactory.newDefaultInstance(); // JDK-default implementation
Transformer tr0 = factory.newTransformer();
Writer w0 = new StringWriter();
tr0.transform(new DOMSource(dom), new StreamResult(w0));

...我保持原始 XML 不变(保留所有

x:
p:
命名空间前缀)。

但是,当我尝试使用 XSLT 身份转换来转换它时...

<transform version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
    <output method="xml" encoding="UTF-8" indent="no" omit-xml-declaration="no" />
    <template match="*|@*|node()">
        <copy><apply-templates select="*|@*|node()" /></copy>
    </template>
</transform>
Transformer tr1 = factory.newTransformer(new StreamSource(new StringReader(xsltString)));
Writer w1 = new StringWriter();
tr1.transform(new DOMSource(dom), new StreamResult(w1));

...我得到以下 XML(删除了所有名称空间前缀):

<?xml version="1.0" encoding="UTF-8"?><books xmlns:p="urn:property" xmlns:x="urn:collection">
  <book id="bk001">
    <author>Writer</author>
    <title>The First Book</title>
    <genre>Fiction</genre>
  </book>
</books>

考虑到在我的代码库中,我无法控制 DOM 的创建方式(它可能是命名空间感知的,也可能是不感知的,在大多数情况下是后者),我如何编写一个 XSLT 1.0 转换来始终保留所有 XML 命名空间前缀
(身份转换是一个例子,我想在将来编写更复杂的转换)

我可以在 TransformerFactory 上设置任何属性,或者对 XSLT

match="..."
属性进行任何更改来实现此目的吗?

java xml xslt
1个回答
0
投票

XSLT 被定义为在命名空间感知的数据模型上运行。如果您向其提供不支持命名空间的输入,则结果是未定义的,并且不同的处理器给出不同的结果您不应该感到惊讶。

是的,有一个真正的问题,当你拿到一个 DOM 时,你无法判断它是否支持命名空间。我的建议是将 DOM 扔进历史的垃圾箱;我知道这不切实际,但如果你不这样做,你就必须忍受它的问题。

© www.soinside.com 2019 - 2024. All rights reserved.