java - 使用 XSLT 1.0 更新 XML 节点属性失败
问题描述
我正在使用带有 XSLT 1.0 的 Java 8。
我将以下 xml 文件用作 XSLT 的输入
<?xml version="1.0" encoding="UTF-8"?>
<Research xmlns="http://www.rixml.org/2013/2/RIXML">
<Product>
<StatusInfo statusType="Revised"/>
</Product>
</Research>
我正在尝试将 statusType 属性从当前值更新为 Deleted,下面是执行相同操作的 xslt。
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="//Research/Product/StatusInfo">
<xsl:element name="StatusInfo">
<xsl:attribute name="stausType">Deleted</xsl:attribute>
</xsl:element>
</xsl:template>
但是当我尝试使用下面的 Java 程序应用 xslt 时,它没有给出任何错误,但它无法更新新生成的 xml 中的 statusType。
一旦我删除了 Research 元素的 xmlns 属性并应用了相同的 xslt,它就会正确更新该属性。
我正在使用下面的 Java 程序在输入文件上应用 xslt 以生成最终输出文件。
公共类 TestPullbackRIXMLXSLT1 {
private static final String SOURCE_XSLT_PATH="C:\\MDERedesignPoc\\distribution-engine-publications\\package\\config\\xslt\\RIXMLPullback.xsl";
private static final String INPUT_XML_FILE_PATH="C:\\export\\rschapps\\rschdistengine\\workarea-qa\\2002434_1_10893_DISTRIBUTE\\core\\input.xml";
private static final String OUTPUT_XML_FILE_PATH="C:\\export\\rschapps\\rschdistengine\\workarea-qa\\2002434_1_10893_DISTRIBUTE\\core\\output.xml";
private static final Logger logger = LoggerFactory.getLogger(TestRIXMLXSLT.class);
public static void main(String[] args) {
try
{
System.out.println("Creation of RIXML 24 ");
Transformer transformer = createTransformer();
StreamSource source = new StreamSource(new File(INPUT_XML_FILE_PATH));
File outputXML=new File(OUTPUT_XML_FILE_PATH);
StreamResult result = new StreamResult(outputXML);
transformer.transform(source, result);
}
catch(Exception e) {
e.printStackTrace();
}
}
private static Transformer createTransformer() throws TransformerConfigurationException{
TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "all");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "all");
Templates cachedXSLT = factory.newTemplates(new StreamSource(new File(SOURCE_XSLT_PATH)));
Transformer transformer = cachedXSLT.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, Constants.YES);
transformer.setOutputProperty(Constants.TRANSFORMER_INDENT_PARAMETER_NAME, Constants.TRANSFORMER_INDENT_PARAMETER_VALUE);
return transformer;
}
}
我无法理解为什么在应用 xslt 时 xmlns 会导致问题,如果属性不存在,一切正常。
我必须在 input.xml 中保留 xmlns(命名空间)属性以避免失败。
有人可以帮我解决这个问题吗?
解决方案
这种问题类型的问题经常回来。您需要考虑命名空间。阅读命名空间。
可以这样做:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ri="http://www.rixml.org/2013/2/RIXML"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="//ri:Research/ri:Product/ri:StatusInfo">
<xsl:element name="StatusInfo" namespace="http://www.rixml.org/2013/2/RIXML">
<xsl:attribute name="statusType">Deleted</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
看到它在这里工作:https ://xsltfiddle.liberty-development.net/ehVZvw8
或者您可以将其简化为:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ri="http://www.rixml.org/2013/2/RIXML"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="ri:StatusInfo/@statusType">
<xsl:attribute name="statusType">Deleted</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
看到它在这里工作:https ://xsltfiddle.liberty-development.net/ehVZvw8/1
推荐阅读
- azure-devops - 在 VSTS 中将配置添加到测试计划
- python - 如何一次分组并连接多列中的多行?
- javascript - 访问 $(this) 值返回未定义的 jquery
- ansible - 配置 ansible 以在远程目标上使用 python3
- sql-server - > all ( ) vs max () 在 SQL Server 中的处理效率和速度
- c# - 如何在 ASP.NET Core 2.2 中使用来自不同托管项目的共享 SignalR Hub
- ruby - Use local version of module from Github instead of installed
- python - Django Channels - 接收 JSON 对象
- java - 休眠异常:不能转换为 [B
- android - 如何在 EditText 中添加一个范围,以便在输入时输入在 Android Studio 中超出范围时以红色突出显示?