2016-07-03 70 views
2

我试图访问属性值的名称访问属性值,但属性名称包含特殊字符,例如:XPath来与具有特殊字符

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <row> 
    <ELEMENT1 at:it="true">W</ELEMENT1>------ 
    <ELEMENT2>IN</ELEMENT2> 
    <ELEMENT3>RP</ELEMENT3> 
    <ELEMENT4>KKK</ELEMENT4> 
    </row> 
    <row> 
    <ELEMENT1 acón='sys'>2</ELEMENT1>------ 
    <ELEMENT2>ARQ</ELEMENT2> 
    <ELEMENT3>MR</ELEMENT3> 
    <ELEMENT4>AC</ELEMENT4> 
    </row> 
    <row> 
    <ELEMENT1>3</ELEMENT1> 
    <ELEMENT2>I</ELEMENT2> 
    <ELEMENT3 at:it="true" >RP</ELEMENT3>------ 
    <ELEMENT4>KKK</ELEMENT4> 
    </row> 
    <row> 
    <ELEMENT1>1</ELEMENT1> 
    <ELEMENT2>CC</ELEMENT2> 
    <ELEMENT3>XX</ELEMENT3> 
    <ELEMENT4 eléct='false' >I</ELEMENT4>------ 
    </row> 
    <row> 
    <ELEMENT1>12</ELEMENT1> 
    <ELEMENT2 at:it="true" >IN</ELEMENT2>------ 
    <ELEMENT3>3</ELEMENT3> 
    <ELEMENT4></ELEMENT4> 
    </row> 
</root> 

如果我改变的名称属性并删除它们特殊字符,我可以访问它们:

at:it ------> atit 
Acón ------> Acon 
eléctr ------> elect 

但属性与特殊字符的名称,我不能XPath查询表达式访问它们。

我如何访问一个XML文件,以获得具有特殊字符名称的属性值?

将XML文件转换为DOM我使用了Java6,javax.xml。 ,org.w3c.dom。

+0

天使,欢迎堆栈溢出。你已经在这里待了几个月,并提出了9个问题,但还没有[**接受**](http://meta.stackoverflow.com/q/5234/234215)或[** upvote **] (http://stackoverflow.com/help/why-vote)任何答案。请阅读链接的页面,并考虑接受和/或upvoting帮助你的答案。谢谢。 – kjhughes

回答

1

认识到,一个冒号(:should只能在一个元件中使用或属性名称如果命名空间前缀的一部分:

在XML建议的命名空间[XML Names]分配一个意思是 包含冒号的名字。因此,除命名空间以外,作者不应在XML名称中使用冒号,但XML 处理器必须接受冒号作为名称字符。

所以,

/root/row/ELEMENT1/@at:it 

将努力选择"true"只要你通过定义at命名空间前缀在XML(最好)改变你的XML,

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:at="http://example.com/at"> 
    <row> 
    <ELEMENT1 at:it="true">W</ELEMENT1>------ 
    <ELEMENT2>IN</ELEMENT2> 
    <ELEMENT3>RP</ELEMENT3> 
    <ELEMENT4>KKK</ELEMENT4> 
    </row> 
    <row> 
    <ELEMENT1 acón='sys'>2</ELEMENT1>------ 
    <ELEMENT2>ARQ</ELEMENT2> 
    <ELEMENT3>MR</ELEMENT3> 
    <ELEMENT4>AC</ELEMENT4> 
    </row> 
    <row> 
    <ELEMENT1>3</ELEMENT1> 
    <ELEMENT2>I</ELEMENT2> 
    <ELEMENT3 at:it="true" >RP</ELEMENT3>------ 
    <ELEMENT4>KKK</ELEMENT4> 
    </row> 
    <row> 
    <ELEMENT1>1</ELEMENT1> 
    <ELEMENT2>CC</ELEMENT2> 
    <ELEMENT3>XX</ELEMENT3> 
    <ELEMENT4 eléct='false' >I</ELEMENT4>------ 
    </row> 
    <row> 
    <ELEMENT1>12</ELEMENT1> 
    <ELEMENT2 at:it="true" >IN</ELEMENT2>------ 
    <ELEMENT3>3</ELEMENT3> 
    <ELEMENT4></ELEMENT4> 
    </row> 
</root> 

或指示您的XML处理器忽略XML名称空间(而不是最佳实践)。

接下来的两个案件是罚款:

/root/row/ELEMENT1/@acón 

将选择"sys"没有问题提供您的XPath处理器支持UTF-8编码(应该)。

/root/row/ELEMENT4/@eléct 

将类似地选择"false"

+0

谢谢,我试过... factory.setNamespaceAware(false); ...但它仍然不能很好地工作......我也尝试过...... factory.setNamespaceAware(true); ...和xsi:它。 ..但不工作..我将继续测试 –

+0

如上所述,除非它是名称空间前缀的一部分,否则不应在元素或属性名称中使用冒号。虽然技术上允许它,但我不惊讶你听到你遇到麻烦。真的,不要这样做。 – kjhughes

0

我用Java 6试了一下,没有问题访问带有重音的属性。冒号是一种特殊情况,因为它用于表示具有名称空间前缀的元素/属性名称。 XML不使用名称空间,否则前缀为at的名称空间声明。

XML解析器有一个开关,用于将冒号作为名称的一部分来处理,但XPath引擎总是可以识别名称空间。但有一点技巧,还可以:

File xmlFile = new File("in.xml"); 
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
// Parse without namespaces. Otherwise parsing leads to an error 
// because there is no namespace declaration for prefix 'at'. 
factory.setNamespaceAware(false); 
DocumentBuilder builder = factory.newDocumentBuilder(); 
Document doc = builder.parse(xmlFile); 

XPathFactory xPathfactory = XPathFactory.newInstance(); 
XPath xpath = xPathfactory.newXPath(); 

XPathExpression expr1 = xpath.compile("/root/row/ELEMENT1/@acón"); 
//XPathExpression expr2 = xpath.compile("/root/row/ELEMENT1/@at:it"); Doesn't work! 
XPathExpression expr2 = xpath.compile("/root/row/ELEMENT1/@*[name() = 'at:it']"); 
XPathExpression expr3 = xpath.compile("/root/row/ELEMENT4/@eléct"); 

System.out.println((String) expr1.evaluate(doc, XPathConstants.STRING)); 
System.out.println((String) expr2.evaluate(doc, XPathConstants.STRING)); 
System.out.println((String) expr3.evaluate(doc, XPathConstants.STRING)); 

输出是:

sys 
true 
false 
+0

...谢谢,我曾尝试过... factory.setNamespaceAware(false); .... 但它仍然无法正常工作 –