2016-02-29 48 views
1

我有一個XML文檔,其中有固定的結構,但深度是變化的,例如: -的xpath爲xml文檔具有變化的深度

  1. 它具有主節點<project>
  2. 它有可能重複多次的子節點<namespace>。在<namespace>之前或之後可能會出現一些新標籤。
<project> 
<newtag> 
<namespace> 
    <namespace> 
    .......... 
    </namespace> 
</namespace> 
</newtag> 
</project> 
  • 後多個命名空間有我的興趣<querySubject>的兩個標籤和<queryItem>
  • 我正在尋找一個文本在使用特定XPATH的queryItem標記中: -

    /project/namespace/namespace/querySubject/queryItem[contains(., 'searchTerm')]/ancestor-or-self::*/name 
    

    我的XPath是工作的罰款下面給出一個特定的結構: -

    <project> 
    <namespace> 
         <name locale="en">Test</name> 
         <lastChanged>2016-01-12T12:42:46</lastChanged> 
          <namespace> 
          <name locale="en">Database Layer</name> 
           <querySubject status="valid"> 
           <name locale="en">qskxyz</name> 
            <queryItem> 
            <name locale="en">qixyz</name> 
             <hello>searchTerm</hello> 
            </queryItem> 
           </querySubject> 
          </namespace> 
    </namespace> 
    <namespace> 
         <name locale="en">Test</name> 
         <lastChanged>2016-01-12T12:42:46</lastChanged> 
          <namespace> 
          <name locale="en">Database Layer</name> 
           <querySubject status="valid"> 
           <name locale="en">qsxyz</name> 
            <queryItem> 
            <name locale="en">myName</name> 
             <hello>...Hi there..</hello> 
            </queryItem> 
           </querySubject> 
          </namespace> 
    </namespace> 
    </project> 
    

    但不工作,如果有在上面點描述的變化。任何建議

    編輯1.

    有以我的觀察有些想念

    我的實際項目標籤

    <project containsDynamicContent="false" xmlns="http://www.developer.cognos.com/schemas/bmt/60/7" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.developer.cognos.com/schemas/bmt/60/7 BMTModelSpecification.xsd"> 
    

    然而在開發中,我採取簡單<project></project>

    這是影響和我的Xpath不工作。 任何建議我嘗試下面的XPath,但是這也不能正常工作,我不能改變我的XML標籤.. 我已經嘗試過這個XPath: -

    //namespace//querySubject/queryItem[contains(.,'searchTerm')]/ancestor-or-self::*/name 
    
    +0

    *。*> 「我使用的是特定的XPATH搜索在queryItem標籤的文本」,但你的XPath表達式選擇是祖先(所有'name'節點或自我)從您選擇的'queryItem'開始。這是矛盾的。 –

    +0

    是的,我正在爲文本進行插入操作,然後返回所有祖先名稱以進行跟蹤 – user2816085

    +0

    [XML元素具有命名空間,我的XPATH無法正常工作]的可能重複(http://stackoverflow.com/questions/10981312/xml-element -has-namespace-my-xpath-does-not-work) – user2816085

    回答

    1

    基本上,XPath表達式爲:

    /x:project//x:namespace//x:querySubject/x:queryItem[contains(.,'searchTerm')]/ancestor-or-self::*/x:name 
    

    然後,您需要將名稱空間http://www.developer.cognos.com/schemas/bmt/60/7與前綴x相關聯。


    我將以Java(1.7)中的代碼片段爲例說明。這使用XPath表達式註冊NamespaceContext,該表達式解析了前綴的名稱空間(在本例中爲x)。該片段是一個裸露的例子,它甚至不檢查哪個前綴被傳遞給NamespaceContext.getNamespaceURI。典型的實現使用映射將URI映射到前綴。

    其他開發環境應該具有類似的功能。


    import java.io.StringReader; 
    import java.util.Iterator; 
    import javax.xml.namespace.NamespaceContext; 
    import javax.xml.xpath.*; 
    import org.w3c.dom.NodeList; 
    import org.xml.sax.InputSource; 
    
    public class XPathInXmlns { 
        private static final String xml= 
    "<project containsDynamicContent=\"false\" xmlns=\"http://www.developer.cognos.com/schemas/bmt/60/7\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.developer.cognos.com/schemas/bmt/60/7 BMTModelSpecification.xsd\">"+ 
    " <namespace>"+ 
    "   <name locale=\"en\">Test</name>"+ 
    "   <lastChanged>2016-01-12T12:42:46</lastChanged>"+ 
    "    <namespace>"+ 
    "    <name locale=\"en\">Database Layer</name>"+ 
    "     <querySubject status=\"valid\">"+ 
    "     <name locale=\"en\">qskxyz</name>"+ 
    "      <queryItem>"+ 
    "      <name locale=\"en\">qixyz</name>"+ 
    "       <hello>searchTerm</hello>"+ 
    "      </queryItem>"+ 
    "     </querySubject>"+ 
    "    </namespace>"+ 
    " </namespace>"+ 
    " <namespace>"+ 
    "   <name locale=\"en\">Test</name>"+ 
    "   <lastChanged>2016-01-12T12:42:46</lastChanged>"+ 
    "    <namespace>"+ 
    "    <name locale=\"en\">Database Layer</name>"+ 
    "     <querySubject status=\"valid\">"+ 
    "     <name locale=\"en\">qsxyz</name>"+ 
    "      <queryItem>"+ 
    "      <name locale=\"en\">myName</name>"+ 
    "       <hello>...Hi there..</hello>"+ 
    "      </queryItem>"+ 
    "     </querySubject>"+ 
    "    </namespace>"+ 
    " </namespace>"+ 
    " </project>"; 
    
        private static final String xpathExpr= 
    "/x:project//x:namespace//x:querySubject/x:queryItem[contains(.,'searchTerm')]/ancestor-or-self::*/x:name/text()"; 
    
        public static void main(String[] args) { 
         try { 
          XPath xpath = XPathFactory.newInstance().newXPath(); 
          xpath.setNamespaceContext(new NamespaceContext() { 
           @Override 
           public Iterator getPrefixes(String namespaceURI) { 
            return null; 
           } 
           @Override 
           public String getPrefix(String namespaceURI) { 
            return null; 
           } 
           @Override 
           public String getNamespaceURI(String prefix) { 
            return "http://www.developer.cognos.com/schemas/bmt/60/7"; 
           } 
          }); 
          XPathExpression expr = xpath.compile(xpathExpr); 
          NodeList nodeList = (NodeList) expr.evaluate(new InputSource(new StringReader(xml)),XPathConstants.NODESET); 
          for(int i = 0; i != nodeList.getLength(); ++i) 
           System.out.println(nodeList.item(i).getNodeValue()); 
         } catch (XPathExpressionException e) { 
          e.printStackTrace(); 
         } 
        } 
    } 
    

    輸出:

    Test 
    Database Layer 
    qskxyz 
    qixyz 
    
    +0

    我認爲我在xml中缺少了一些東西,因爲它不起作用。在發現 – user2816085

    +0

    @ user2816085後會更新我使用xml進行了測試,之前添加了隨機元素並且在命名空間元素之後,插入了多個附加名稱空間...對我有用。 –

    +0

    所以這個問題變成了http://stackoverflow.com/questions/10981312/xml-element-has-namespace-my-xpath-does-not-work的複本 – user2816085