XPath ile ad alanları nasıl yok sayılır


111

Amacım, XPath kullanarak birden çok ad alanına sahip birden çok xml dosyasından belirli düğümleri çıkarmaktır. Ad alanı URI'lerini bildiğim sürece her şey yolunda gidiyor. Ad alanı adının kendisi sabit kalır, ancak Şemalar (XSD) bazen istemci tarafından oluşturulur, yani benim için bilinmiyor. O zaman temelde üç seçenekle kaldım:

  1. ad alanı için yalnızca bir şema kullanın, hiçbir şeyin ters gitmemesini umuyoruz (emin olabilir miyim?)

  2. belgenin alt düğümlerini alın ve bir ad alanı URI'si olan ilk düğümü arayın, orada olmasını umarak ve sadece URI'yi kullanın, doğru olanı umarak. birçok nedenden dolayı yanlış gidebilir

  3. bir şekilde xpath'e şunu söyleyin: "bak, isim alanlarını umursamıyorum, sadece bu isimdeki TÜM düğümleri bul, sana isim alanının adını bile söyleyebilirim, sadece URI'yi değil." Ve buradaki soru bu ...

Bu, burada veya burada bulunan sayısız "xpath ifadem işe yaramıyor çünkü ad alanı farkındalığının farkında değilim" sorusunun tekrarı değil . İsim alanı farkındalığını nasıl kullanacağımı biliyorum. Sadece ondan nasıl kurtulacağımı değil.


2
Şemaları bilmiyorsanız, hangi öğeleri istediğinizi nasıl bilebilirsiniz?
Paul Butcher


1
işaret ettiğin için teşekkürler, Alejandro. "Xpath ad alanını yoksay" araması bunu ortaya çıkarmış olmalıydı, ancak
olmadı

2
@kostja: SO arama kutusu ile arama yapmayın, işe yaramaz ... Bir dahaki sefere Google'ı deneyin. Aslında, bu SO ekibi tarafından teşvik edilmektedir.

1
Google site araması aslında SO'da yararlı şeyler bulma konusunda daha iyi bir iş çıkarır. Neden varsayılan olarak bir seçenek olmadığını merak ediyorum. Tekrar teşekkürler, Alejandro
kostja

Yanıtlar:


166

local-name()XPath işlevini kullanabilirsiniz . Gibi bir düğüm seçmek yerine

/path/to/x:somenode

tüm düğümleri seçebilir ve doğru yerel ada sahip olanı filtreleyebilirsiniz:

/path/to/*[local-name() = 'somenode']

9
Ayrıca local-name(), ad alanı farkında olmadan özniteliklere başvurmak için de kullanabilirsiniz , bkz .: stackoverflow.com/q/21239181/274677
Marcus Junius Brutus


1
Çok basit. öğleden sonramı kurtardım.
C Johnson


3

Bir XmlTextReader'da Namespace = false kullanabilirsiniz

[TestMethod]
public void MyTestMethod()
{
    string _withXmlns = @"<?xml version=""1.0"" encoding=""utf-8""?>
<ParentTag xmlns=""http://anyNamespace.com"">
<Identification value=""ID123456"" />
</ParentTag>
";

    var xmlReader = new XmlTextReader(new MemoryStream(Encoding.Default.GetBytes(_withXmlns)));

    xmlReader.Namespaces = false;

    var content = XElement.Load(xmlReader);

    XElement elem = content.XPathSelectElement("/Identification");

    elem.Should().NotBeNull();
    elem.Attribute("value").Value.Should().Be("ID123456");
}

ile :

using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

XPath aracılığıyla bir düğüm seçmek için bu çalışır; Maalesef bir 'The 'xmlns' attribute is bound to the reserved namespacehata nedeniyle belgeyi kaydedemiyorsunuz .
AutomatedChaos

2

Veya ad () kullanabilirsiniz:

/path/to/*[name() = 'somenode']

Veya yalnızca arama öznitelikleri:

//*[@attribute="this one"]

Xml'yi bir powershell nesnesi olarak açarsanız, ad alanlarını yok sayar:

[xml]$xml = get-content file.xml
$xml.path.to.somenode

0

Qt C ++ 'daki örneğim. Qt, XPath 2.0'ı destekler:

    QString planePath = ":/Models/Plane.dae";
    QFile f(planePath);
    if (!f.open(QIODevice::ReadOnly))
    {
        std::cerr << "Failed to load the file: " <<
                     planePath.toStdString() << std::endl;
        return;
    }

    QXmlQuery query;
    query.bindVariable("myFile", &f);
//    query.setQuery("doc($myFile)//*[local-name() = 'p']/text()"); // it works too but it is XPath 1.0
    query.setQuery("doc($myFile)//*:p/text()");

    QString result;
    query.evaluateTo(&result);
    qDebug() << result;
    f.close();

Program çıkışı: "1 0 0 2 0 1 0 0 2 1 0 3 3 0 4 2 0 5\n"

Plane.dae

<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <asset>
    <contributor>
      <author>Blender User</author>
      <authoring_tool>Blender 2.83.3 commit date:2020-07-22, commit time:06:01, hash:353e5bd7493e</authoring_tool>
    </contributor>
    <created>2020-08-03T14:03:19</created>
    <modified>2020-08-03T14:03:19</modified>
    <unit name="meter" meter="1"/>
    <up_axis>Z_UP</up_axis>
  </asset>
  <library_effects>
    <effect id="PlaneMaterial-effect">
      <profile_COMMON>
        <technique sid="common">
          <lambert>
            <emission>
              <color sid="emission">0 0 0 1</color>
            </emission>
            <diffuse>
              <color sid="diffuse">0.01664001 0.8000001 0.01191879 1</color>
            </diffuse>
            <reflectivity>
              <float sid="specular">0.5</float>
            </reflectivity>
          </lambert>
        </technique>
      </profile_COMMON>
    </effect>
  </library_effects>
  <library_images/>
  <library_materials>
    <material id="PlaneMaterial-material" name="PlaneMaterial">
      <instance_effect url="#PlaneMaterial-effect"/>
    </material>
  </library_materials>
  <library_geometries>
    <geometry id="Plane-mesh" name="Plane">
      <mesh>
        <source id="Plane-mesh-positions">
          <float_array id="Plane-mesh-positions-array" count="12">-1 -1 0 1 -1 0 -1 1 0 1 1 0</float_array>
          <technique_common>
            <accessor source="#Plane-mesh-positions-array" count="4" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <source id="Plane-mesh-normals">
          <float_array id="Plane-mesh-normals-array" count="3">0 0 1</float_array>
          <technique_common>
            <accessor source="#Plane-mesh-normals-array" count="1" stride="3">
              <param name="X" type="float"/>
              <param name="Y" type="float"/>
              <param name="Z" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <source id="Plane-mesh-map-0">
          <float_array id="Plane-mesh-map-0-array" count="12">1 0 0 1 0 0 1 0 1 1 0 1</float_array>
          <technique_common>
            <accessor source="#Plane-mesh-map-0-array" count="6" stride="2">
              <param name="S" type="float"/>
              <param name="T" type="float"/>
            </accessor>
          </technique_common>
        </source>
        <vertices id="Plane-mesh-vertices">
          <input semantic="POSITION" source="#Plane-mesh-positions"/>
        </vertices>
        <triangles material="PlaneMaterial-material" count="2">
          <input semantic="VERTEX" source="#Plane-mesh-vertices" offset="0"/>
          <input semantic="NORMAL" source="#Plane-mesh-normals" offset="1"/>
          <input semantic="TEXCOORD" source="#Plane-mesh-map-0" offset="2" set="0"/>
          <p>1 0 0 2 0 1 0 0 2 1 0 3 3 0 4 2 0 5</p>
        </triangles>
      </mesh>
    </geometry>
  </library_geometries>
  <library_visual_scenes>
    <visual_scene id="Scene" name="Scene">
      <node id="Plane" name="Plane" type="NODE">
        <matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
        <instance_geometry url="#Plane-mesh" name="Plane">
          <bind_material>
            <technique_common>
              <instance_material symbol="PlaneMaterial-material" target="#PlaneMaterial-material">
                <bind_vertex_input semantic="UVMap" input_semantic="TEXCOORD" input_set="0"/>
              </instance_material>
            </technique_common>
          </bind_material>
        </instance_geometry>
      </node>
    </visual_scene>
  </library_visual_scenes>
  <scene>
    <instance_visual_scene url="#Scene"/>
  </scene>
</COLLADA>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.