使用XPath选择XML节点时如何忽略命名空间
我必须解析如下所示的XML文档:使用XPath选择XML节点时如何忽略命名空间,xml,xpath,namespaces,xml-namespaces,Xml,Xpath,Namespaces,Xml Namespaces,我必须解析如下所示的XML文档: <?xml version="1.0" encoding="UTF-8" ?> <m:OASISReport xmlns:m="http://oasissta.caiso.com/mrtu-oasis/xsd/OASISReport.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLo
<?xml version="1.0" encoding="UTF-8" ?>
<m:OASISReport xmlns:m="http://oasissta.caiso.com/mrtu-oasis/xsd/OASISReport.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://oasissta.caiso.com/mrtu-oasis/xsd/OASISReport.xsd http://oasissta.caiso.com/mrtu-oasis/xsd/OASISReport.xsd">
<m:MessagePayload>
<m:RTO>
<m:name>CAISO</m:name>
<m:REPORT_ITEM>
<m:REPORT_HEADER>
<m:SYSTEM>OASIS</m:SYSTEM>
<m:TZ>PPT</m:TZ>
<m:REPORT>AS_RESULTS</m:REPORT>
<m:MKT_TYPE>HASP</m:MKT_TYPE>
<m:UOM>MW</m:UOM>
<m:INTERVAL>ENDING</m:INTERVAL>
<m:SEC_PER_INTERVAL>3600</m:SEC_PER_INTERVAL>
</m:REPORT_HEADER>
<m:REPORT_DATA>
<m:DATA_ITEM>NS_PROC_MW</m:DATA_ITEM>
<m:RESOURCE_NAME>AS_SP26_EXP</m:RESOURCE_NAME>
<m:OPR_DATE>2010-11-17</m:OPR_DATE>
<m:INTERVAL_NUM>1</m:INTERVAL_NUM>
<m:VALUE>0</m:VALUE>
</m:REPORT_DATA>
凯索
绿洲
幻灯片演示文件
结果
搭扣
兆瓦
结束
3600
NS_程序(MW)
AS_SP26_EXP
2010-11-17
1.
0
问题是名称空间“http://oasissta.caiso.com/mrtu-oasis/xsd/OASISReport.xsd“有时可能会有所不同。我想完全忽略它,只是从标记MessagePayload下游获取数据
我目前使用的代码是:
String[] namespaces = new String[1];
String[] namespaceAliases = new String[1];
namespaceAliases[0] = "ns0";
namespaces[0] = "http://oasissta.caiso.com/mrtu-oasis/xsd/OASISReport.xsd";
File inputFile = new File(inputFileName);
Map namespaceURIs = new HashMap();
// This query will return all of the ASR records.
String xPathExpression = "/ns0:OASISReport
/ns0:MessagePayload
/ns0:RTO
/ns0:REPORT_ITEM
/ns0:REPORT_DATA";
xPathExpression += "|/ns0:OASISReport
/ns0:MessagePayload
/ns0:RTO
/ns0:REPORT_ITEM
/ns0:REPORT_HEADER";
// Load up the raw XML file. The parameters ignore whitespace and other
// nonsense,
// reduces DOM tree size.
SAXReader reader = new SAXReader();
reader.setStripWhitespaceText(true);
reader.setMergeAdjacentText(true);
Document inputDocument = reader.read(inputFile);
// Relate the aliases with the namespaces
if (namespaceAliases != null && namespaces != null)
{
for (int i = 0; i < namespaceAliases.length; i++)
{
namespaceURIs.put(namespaceAliases[i], namespaces[i]);
}
}
// Cache the expression using the supplied namespaces.
XPath xPath = DocumentHelper.createXPath(xPathExpression);
xPath.setNamespaceURIs(namespaceURIs);
List asResultsNodes = xPath.selectNodes(inputDocument.getRootElement());
String[]名称空间=新字符串[1];
字符串[]名称空间别名=新字符串[1];
名称空间别名[0]=“ns0”;
名称空间[0]=”http://oasissta.caiso.com/mrtu-oasis/xsd/OASISReport.xsd";
文件inputFile=新文件(inputFileName);
Map namespaceURIs=new HashMap();
//此查询将返回所有ASR记录。
字符串xPathExpression=“/ns0:OAISreport
/ns0:MessagePayload
/ns0:RTO
/ns0:报告项目
/ns0:报告_数据”;
xPathExpression+=“|/ns0:OAISreport
/ns0:MessagePayload
/ns0:RTO
/ns0:报告项目
/ns0:报告标题“;
//加载原始XML文件。这些参数忽略空格和其他字符
//胡说,
//减少DOM树的大小。
SAXReader=新SAXReader();
reader.setStripWhitespaceText(true);
reader.setMergeAdjacentText(true);
文档inputDocument=reader.read(inputFile);
//将别名与名称空间关联
if(名称空间别名!=null&&namespaces!=null)
{
for(int i=0;i
如果名称空间从未更改,则可以正常工作,但情况显然并非如此。我需要做什么才能使它忽略名称空间?或者,如果我知道所有可能的名称空间值的集合,如何将它们全部传递给XPath实例?这是常见问题解答(但我现在懒得搜索重复的名称空间值) 在XPath1.0中
//*[local-name()='name']
选择“名称”为本地名称的任何元素
在XPath 2.0中,您可以使用:
//*:name
使用:
/*/*/*/*/*
[local-name()='REPORT_DATA'
or
local-name()='REPORT_HEADER'
]
有人想要更完整的语法吗?
String xPathExpression = "/*[local-name()='OASISReport]
/*[local-name()='MessagePayload]
/*[local-name()='RTO]
/*[local-name()='REPORT_ITEM]
/*[local-name()='REPORT_DATA"];
顺便说一句,如果XPath还需要元素索引位置:
String xPathExpression = "/*[local-name()='OASISReport][1]
@user452103:XPath是XML名称,所以它永远不会忽略名称空间。可以使用选择有关命名空间的节点的表达式。如果名称空间URI经常更改,那么就是错误的URI。名称空间URI假设指示元素属于特定的XML词汇表。@user452103:保留此格式,它会更清晰。@Alejandro:谢谢您的格式设置,现在看起来确实更好了。无论名称空间如何,我都可以使用什么表达式来选择节点?好问题,+1。请参阅我的答案,了解选择所需节点的单个XPath 1.0表达式。:)您的意思是在上面的代码中将其用作xPathExpression的值吗?@user452103:是的,完全正确。这是要使用的XPath表达式。因此,为了澄清一下,它现在应该是这样的:String xPathExpression=“/*/*/*/*/*/*/*/*[local-name()='REPORT\u DATA'或local-name()='REPORT\u HEADER']”@用户452103:是的,你为什么不试试呢?此表达式选择提供的XML文档中需要的两个节点。@ClaraOnager,此表达式选择顶部以下第四级的任何元素,其local-name()为“REPORT\u DATA”或“REPORT\u HEADER”