2017-07-20 161 views
1

我有一個具有CDATA的XML,其中包含具有與&符號的URL的標記。我應該使用lxml來讀取這些標籤,但我得到一個錯誤。lxml和CDATA和&

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "src\lxml\lxml.etree.pyx", line 3228, in lxml.etree.fromstring (src\lxml\lxml.etree.c:79593) 
    File "src\lxml\parser.pxi", line 1848, in lxml.etree._parseMemoryDocument (src\lxml\lxml.etree.c:119112) 
    File "src\lxml\parser.pxi", line 1729, in lxml.etree._parseDoc (src\lxml\lxml.etree.c:117670) 
    File "src\lxml\parser.pxi", line 1063, in lxml.etree._BaseParser._parseUnicodeDoc (src\lxml\lxml.etree.c:111657) 
    File "src\lxml\parser.pxi", line 595, in lxml.etree._ParserContext._handleParseResultDoc (src\lxml\lxml.etree.c:105880) 
    File "src\lxml\parser.pxi", line 706, in lxml.etree._handleParseResult (src\lxml\lxml.etree.c:107588) 
    File "src\lxml\parser.pxi", line 635, in lxml.etree._raiseParseError (src\lxml\lxml.etree.c:106442) 
    File "<string>", line 9 
lxml.etree.XMLSyntaxError: EntityRef: expecting ';', line 9, column 98 

我怎麼能通過這個錯誤?我在做我對嗎?我們需要用&替換一些東西嗎?

的代碼如下

from lxml import etree 
ns0_NAMESPACE = "http://webservices.online.webapp.paperless.cl" 
ns0 = "{%s}" % ns0_NAMESPACE 
NSMAP = {'ns0':ns0_NAMESPACE} 

response=""" 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Body> 
    <ns:OnlineGeneration2Response xmlns:ns="http://webservices.online.webapp.cl"> 
     <ns:return> 
      <![CDATA[<EstadoDoc> 
      <Estado>Ok<Estado> 
      <RutEmisor>81201000-K</RutEmisor> 
      <TipoDte>52</TipoDte> 
      <FolioM>117620901</FolioM> 
      <Folio>25022</Folio> 
      <Glosa>NO INFORMADO</Glosa> 
      <UrlDte>http://G500603svGLH:8080/Facturacion/XMLServlet?docId=&uR1v4VhQHvkPrUZDtY6hMg==</UrlDte> 
      </EstadoDoc> 
      <EstadoLote> 
       <UrlPdf>http://G500603svGLH:8080/Facturacion/PDFServlet?docId=uR1v4VhQHvmQJLl22c1DFOLW3c4qbQ47</UrlPdf> 
       <UrlCaratula>http://G500603svGLH:8080/Facturacion/XMLServlet?docId=&uR1v4VhQHvmQJLl22c1DFOLW3c4qbQ47</UrlCaratula> 
      </EstadoLote>]]> 
     </ns:return> 
    </ns:OnlineGeneration2Response> 
    </soapenv:Body> 
</soapenv:Envelope>""" 
root=etree.fromstring(response) 
sub_element=root.xpath('//ns0:return',namespaces=NSMAP) 
print sub_element.text 
if sub_element: 
    sub_element=sub_element[0] 
EstadoDoc_root=etree.fromstring(sub_element.text) 

回答

1

使用XML解析器的恢復選項:

parser = etree.XMLParser(recover=True) 

EstadoDoc_root = etree.fromstring(sub_element.text, parser=parser) 

然後搶網址(或更改爲任何你需要):

print [x.text for x in EstadoDoc_root.xpath('//UrlCaratula|//UrlPdf')] 

['http://G500603svGLH:8080/Facturacion/PDFServlet?docId=uR1v4VhQHvmQJLl22c1DFOLW3c4qbQ47', 
'http://G500603svGLH:8080/Facturacion/XMLServlet?docId='] 

第二url缺少的一部分網址後面的& ...有沒有辦法避免這種情況?

使用HTML解析器來規範和處理違反字符(注意是小寫標籤)

from lxml import html 
EstadoDoc_root = html.fromstring(sub_element) 

print [x.text for x in EstadoDoc_root.xpath('//urlcaratula|//urlpdf')] 

['http://G500603svGLH:8080/Facturacion/PDFServlet?docId=uR1v4VhQHvmQJLl22c1DFOLW3c4qbQ47', 
'http://G500603svGLH:8080/Facturacion/XMLServlet?docId=&uR1v4VhQHvmQJLl22c1DFOLW3c4qbQ47'] 
+0

第二url缺少來自後&... URL的一部分是有辦法避免這種情況?感謝您的回答。 – Guddu

+0

@Guddu請參閱編輯。 – salparadise

+0

謝謝。你完全搖滾!這將幫助我繼續。一個問題,但。爲什麼我在執行下面的代碼時看到無?在[EstadoDoc_root.xpath('// estado')]中打印[x.text for x] – Guddu

1

的問題是,<ns:return>元素的文本(CDATA部分)的內容是不合法的XML。如果在將該文本傳遞給etree.fromstring之前,在該文本中將&替換爲&amp;,則解析應該成功。通常,將XML隱藏在CDATA節中並不是一個好主意;這只是它可能導致的問題的一個例子。如果你對生成這個XML的方有任何影響,我建議試着讓它們改變它。