我正在尝试从XML文档中提取元素(作为字符串)。我已经尝试过此SO答案中建议的两种方法(此处也建议使用类似的方法),但它们都无法正确考虑可能在某些外部文档中定义的名称空间前缀。
使用以下代码:
// entry point method; see exampes of values for the String `s` in the question
public static String stripPayload(String s) throws Exception {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final Document doc = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(s)));
final XPath xPath = XPathFactory.newInstance().newXPath();
final String xPathToGetToTheNodeWeWishToExtract = "/*[local-name()='envelope']/*[local-name()='payload']";
final Node result = (Node) xPath.evaluate(xPathToGetToTheNodeWeWishToExtract, doc, XPathConstants.NODE);
return nodeToString_A(result); // or: nodeToString_B(result)
}
public static String nodeToString_A(Node node) throws Exception {
final StringWriter buf = new StringWriter();
final Transformer xform = TransformerFactory.newInstance().newTransformer();
xform.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
xform.setOutputProperty(OutputKeys.STANDALONE, "yes");
xform.transform(new DOMSource(node), new StreamResult(buf));
return(buf.toString());
}
public static String nodeToString_B(Node node) throws Exception {
final Document document = node.getOwnerDocument();
final DOMImplementationLS domImplLS = (DOMImplementationLS) document.getImplementation();
final LSSerializer serializer = domImplLS.createLSSerializer();
final String str = serializer.writeToString(node);
return str;
}
如果该stripPayload
方法如果传递了以下字符串:
<envelope><payload><a></a><b></b></payload></envelope>
要么
<envelope><p:payload xmlns:p='foo'><a></a><b></b></p:payload></envelope>
......都nodeToString_A
和nodeToString_B
方法的工作。但是,如果我传递以下同样有效的XML文档,其中在外部元素中定义了名称空间前缀:
<envelope xmlns:p='foo'><p:payload><a></a><b></b></p:payload></envelope>
…然后,这两种方法都会失败,因为它们只是发出:
<p:payload><a/><b/></p:payload>
因此,由于忽略了名称空间前缀定义,他们已经在生成无效的文档。
下面更复杂的示例(在属性中使用名称空间前缀):
<envelope xmlns:p='foo' xmlns:a='alpha'><p:payload a:attr='dummy'><a></a><b></b></p:payload></envelope>
……实际上导致nodeToString_A
失败并带有异常,而至少nodeToString_B
会产生无效:
<p:payload a:attr="dummy"><a/><b/></p:payload>
(同样,前缀未定义)。
所以我的问题是:
什么是一种健壮的方法来提取内部XML元素并对其进行字符串化,从而处理可能在某些外部元素中定义的名称空间前缀?
您只需要启用 name-space-awareness即可 。
public static String stripPayload(String s) throws Exception {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
...
}
输出将是…
<p:payload xmlns:p="foo"><a/><b/></p:payload>
我有一个有趣的情况,我的XML编辑器(Oxygen,使用Xerces XML处理器)需要根标签上的前缀,但是我的JAXB XML Marshaller(也是基于Xerces的)不需要根标签上的前缀。我正在试图理解这种情况。 首先是2个模式文件: ns1.xsd ns2。xsd 目前的氧气释放(16.1)需要我称之为“版本1”的东西 版本1 如果我像下面的示例(版本1)那样删除前缀: 版本2 氧气抱
使用xslt 1.0(BizTalk 2016)我正在寻找一种通用的方法来选择任何有效的xml文档的命名空间 例如,我有以下xml文档: 假设根元素的值可以是任何东西,那么选择名称空间值的xpath是什么http://www.random.com/bo/request/portfolioactivation 我原本希望“/*/@xmlns”能起作用,但事实并非如此。
我想知道是否有一种方法来强制JAXB创建与XSD模式相同的名称空间前缀。即,即使我从一个包含xmlns:cts=“http://cts.com”的模式创建JAXB类,在封送类之后,我得到一个具有xmlns:ns1前缀的XML。我知道我可以通过使用NamespacePrefixMapper类来重写这些,但是为什么我需要在我的XSD明确定义了默认前缀的情况下手动执行此操作呢?在我当前的XML中有大量的
问题内容: 除了包级别注释外,还有其他方法可以使用注释来控制自定义名称空间前缀。 可以在元素级别完成吗?也可能有一个带有多个前缀的名称空间吗? 问题答案: 您实际上想做什么?为什么名称空间前缀对您很重要? 对于命名空间前缀,没有标准的元素级注释。 我知道的控制名称空间前缀的选项是: 你已经提到过。 提供习俗。 XML的低级处理(例如,在StAX,SAX或DOM级别)。 我也可以想象: / 通常使用
面临使用JAXB解组的问题。我需要使用多个名称空间。Java类是为第三方提供的XSD生成的。因此,我不想在Java类中的XMLRootElement指定名称空间,也不想手动更改多个类。 编组逻辑如下: xmlelement类TokenRequest.java BasicInRequestType.java 我在package-info.java中指定了前缀 TokenRequest元素实际上引用了
问题内容: 我有一个需要打开并进行一些更改的xml文件,其中之一是删除名称空间和前缀,然后保存到另一个文件。这是xml: 我可以进行所需的其他更改,但是找不到如何删除名称空间和前缀的方法。这是我需要的reusklt xml: 这是我的脚本,它将打开并解析xml并将其保存: 那么,如何在脚本中添加代码以删除名称空间和前缀呢? 问题答案: 按照Uku Loskit的建议替换标签。除此之外,请使用lxm