为什么XML中出现的实体引用中实体名称必须紧接着'&'后面?

13

我在D盘目录下有一个名为/NewFile.xml的XML文件,其中包含以下细节:

<?xml version="1.0"?>
<project>

<logindetails id="1001">
  <url>https:xxx</url>
        <username>xxx</username>
        <password>xxx</password>
</logindetails >

<kpi id="1001">
  <id_r>reports</id_r>
  <id_e>extranet</id_e>
  <id_pr>ext-pr</id_pr>
</kpi> 

<prkpi id="1001">
        <id_1>ext-pr-backlog-age</id_1>
  <id_2>ext-timetoassign-prs</id_2>
  <id_3>ext-timetodeliver-prs</id_3>
  <id_4>ext-timetoresolve-prs</id_4>
  <id_5>ext-new-prs</id_5>

</prkpi>

<filtersection id="1001">
  <visualizationId>Day,Week,Month,Quarter,Semester,Year,RD Tech Group,ICC,Center,Software Pack,Product,Project,Customer PRs,Severity,Priority</visualizationId>
  <projectId>dev/v4.3/r4/e12sqq,BATS,1523 Business IAD & Business CPE,[CoCo2M],VQM</projectId>
</filtersection>

</project>

我在eclipse中运行以下代码:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;


import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class A {

    
    static Properties p= new Properties();
    String url=p.getProperty("url");
    private static Logger Log = Logger.getLogger(A.class.getName());

    public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, InterruptedException {
     WebDriver driver = new FirefoxDriver();
        A a = new A();
      
     Actions actions = new Actions(driver);
     DOMConfigurator.configure("src/log4j.xml");
        String url = a.readXML("logindetails","url");
        String username = a.readXML("logindetails","username");
        String password = a.readXML("logindetails","password");
     
        //use username for webdriver specific actions
        Log.info("Sign in to the OneReports website");
        driver.manage().window().maximize();
        driver.get(url);
        Thread.sleep(5000);
        Log.info("Enter Username");
        driver.findElement(By.id("loginUsername")).sendKeys(username);
        Log.info("Enter Password");
        driver.findElement(By.id("loginPassword")).sendKeys(password); 
        //submit
        Log.info("Submitting login details");
        waitforElement(driver,120 , "//*[@id='submit']");
        driver.findElement(By.id("submit")).submit();
        Thread.sleep(5000);

       Log.info("Clicking on Reports link");
         String id_r = a.readXML("kpi","id_r");
         WebElement menuHoverLink = driver.findElement(By.id(id_r));
       actions.moveToElement(menuHoverLink).perform();
       Thread.sleep(6000);
      
      String id_e = a.readXML("kpi","id_e");
      WebElement menuHoverLink1 = driver.findElement(By.id(id_e));
      actions.moveToElement(menuHoverLink1).perform();
     Thread.sleep(6000);
     
     String id_pr = a.readXML("kpi","id_pr");
     WebElement menuHoverLink2 = driver.findElement(By.id(id_pr));
     actions.moveToElement(menuHoverLink2).perform();
     Thread.sleep(6000);
     
     String id_1 = a.readXML("prkpi","id_1");
     WebElement menuHoverLink3 = driver.findElement(By.id(id_1));
     actions.moveToElement(menuHoverLink3).click().perform();
     Thread.sleep(6000);

    
    
    }

 private static void waitforElement(WebDriver driver, int i, String string) {
  // TODO Auto-generated method stub
  
 }

 public String readXML(String searchelement,String tag) throws SAXException, IOException, ParserConfigurationException{
        String ele = null;
        File fXmlFile = new File("D://NewFile.xml");
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(fXmlFile);
        doc.getDocumentElement().normalize();
        NodeList nList = doc.getElementsByTagName(searchelement);
        Node nNode = nList.item(0);
        if (nNode.getNodeType() == Node.ELEMENT_NODE) {
         Element eElement = (Element) nNode;
            ele=eElement.getElementsByTagName(tag).item(0).getTextContent();
        }
        return ele;
    }

}

运行这段代码时,在控制台中出现以下错误:

Fatal Error] NewFile.xml:27:57: The entity name must immediately follow the '&' in the entity reference.
Exception in thread "main" org.xml.sax.SAXParseException; systemId: file:/D:/NewFile.xml; lineNumber: 27; columnNumber: 57; The entity name must immediately follow the '&' in the entity reference.
 at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
 at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
 at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
 at A.readXML(A.java:94)
 at A.main(A.java:40)

请给我解决这个问题的方案。


3
发布那个XML文件,或者至少发布第27行。你可能在其中有一个未转义的&,就像消息所说的那样。 - chrylis -cautiouslyoptimistic-
@chrylis发布了完整的XML文件。 - testing
我发现这是因为XML中的projectId有&符号。但是有没有办法在XML中解析它呢? - testing
1
@User11111 这不是有效的XML,因此大多数解析器都会拒绝它。这个XML是如何产生的,以至于它有无效的值? - JLRishe
2个回答

16

您在其中有一个未转义的 &,正如@chrylis所说消息中所显示的那样。;-)

Business IAD & Business CPE 更改为 Business IAD &amp; Business CPE

另请参阅:XML文档中需要转义哪些字符?


7

在XML文件中不能直接使用&符号(&),请将其改为:

1523 Business IAD & Business CPE

转换为:

1523 Business IAD &amp; Business CPE

这个有些混淆的错误信息之所以出现,是因为当XML处理器看到 & 时,它期望紧接着是一个实体名称或"字符引用",例如 &amp;, &lt;, &#x225b, 等等。所以它在你的名字中看到 &,并没有猜测你使用不正确。


我们能强制XML处理器转义或转换为ASCII字符吗? - newday

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接