2016-10-12 3 views
3

diesen Job Betrachten wir die Arbeit:Lesen von XML mit Standard-Namespace

static void XMLTest(Args _args) 
{ 
    str xml = @'<?xml version="1.0" encoding="UTF-8"?> 
     <tests xmlns="abc"> 
      <test> 
       <testnumber><id>1</id></testnumber> 
       <testname>bla bla</testname> 
      </test> 
     </tests> 
    '; 
    XMlDocument doc = XMLDocument::newXML(xml); 
    XMLNodeList tests = doc.selectNodes('//tests/test'); 
    XMLNode node; 
    for (node = tests.nextNode(); node; node = tests.nextNode()) 
    { 
     info(node.selectSingleNode('testnumber/id').text()); 
     info(node.selectSingleNode('testname').text()); 
    } 
} 

Es gibt "1" und "bla bla" wie erwartet.

nun die zweite Zeile des von xml ändern:

<tests> 

zu:

<tests xmlns="xyz"> 

Jetzt schlägt es etwas zu lesen.

So lesen Sie XML mit einem Standardnamespace?

Antwort

4

Sie könnten es tun, um die strenge Art und Weise über eine Instanz von XMLNamespaceManager wie so

static void XMLTest(Args _args) 
{ 
    str xml = @'<?xml version="1.0" encoding="UTF-8"?> 
     <tests xmlns="abc"> 
      <test> 
       <testnumber><id>1</id></testnumber> 
       <testname>bla bla</testname> 
      </test> 
     </tests> 
    '; 
    XMlDocument doc = XMLDocument::newXML(xml); 
    XMLNamespaceManager nsMgr = new XMLNamespaceManager(new XmlNameTable()); 
    XMLNodeList tests; 
    XMLNode node; 
    ; 

    nsMgr.addNamespace('x', 'abc'); 
    tests = doc.selectNodes("//x:tests/x:test", nsMgr); 

    for (node = tests.nextNode(); node; node = tests.nextNode()) 
    { 
     info(node.selectSingleNode('x:testnumber/x:id', nsMgr).text()); 
     info(node.selectSingleNode('x:testname', nsMgr).text()); 
    } 
} 

Wenn für sicher, dass keine Namenskonflikte auftreten, Sie können den Namespace ignorieren und die Knoten über local-name() wie so

entsprechen
static void XMLTest2(Args _args) 
{ 
    str xml = @'<?xml version="1.0" encoding="UTF-8"?> 
     <tests xmlns="abc"> 
      <test> 
       <testnumber><id>1</id></testnumber> 
       <testname>bla bla</testname> 
      </test> 
     </tests> 
    '; 
    XMlDocument doc = XMLDocument::newXML(xml); 
    XMLNodeList tests = doc.selectNodes("//*[local-name()='tests']/*[local-name()='test']"); 
    XMLNode node; 
    for (node = tests.nextNode(); node; node = tests.nextNode()) 
    { 
     info(node.selectSingleNode("*[local-name()='testnumber']/*[local-name()='id']").text()); 
     info(node.selectSingleNode("*[local-name()='testname']").text()); 
    } 
} 
0

Ein anderer Weg, es, leer das xmlns Attribut der Wurzel zu tun:

static void XMLTest(Args _args) 
{ 
    str xml = @'<?xml version="1.0" encoding="UTF-8"?> 
     <tests xmlns="abc"> 
      <test> 
       <testnumber><id>1</id></testnumber> 
       <testname>bla bla</testname> 
      </test> 
     </tests> 
    '; 
    XMlDocument doc = XMLDocument::newXML(xml); 
    XMLNodeList tests; 
    XMLNode node; 
    ; 
    doc.root().attributes().getNamedItem('xmlns').value(''); // Go away xmlns 
    doc = XMLDocument::newXML(doc.xml());     // Now reread all again 
    tests = doc.selectNodes("//tests/x:test", nsMgr); 
    for (node = tests.nextNode(); node; node = tests.nextNode()) 
    { 
     info(node.selectSingleNode('testnumber/id').text()); 
     info(node.selectSingleNode('testname'.text()); 
    } 
} 

Dies erfordert Reparieren der XML mit doc = XMLDocument::newXML(doc.xml()). Wenn das XML groß ist, gehen Sie zur ersten Lösung von @ DAXaholic.