cách bỏ qua không gian tên với XPath


111

Mục tiêu của tôi là trích xuất các nút nhất định từ nhiều tệp xml với nhiều không gian tên bằng XPath. Mọi thứ hoạt động tốt miễn là tôi biết các URI không gian tên. Bản thân tên không gian tên vẫn không đổi, nhưng các Lược đồ (XSD) đôi khi được tạo bởi máy khách, tức là tôi chưa biết. Sau đó, tôi còn lại cơ bản với ba lựa chọn:

  1. chỉ sử dụng một lược đồ cho không gian tên, hy vọng không có gì sai (tôi có thể chắc chắn không?)

  2. lấy các nút con của tài liệu và tìm kiếm nút đầu tiên có URI không gian tên, hy vọng nó ở đó và chỉ sử dụng URI, hy vọng nó là đúng. có thể sai vì nhiều lý do

  3. bằng cách nào đó nói với xpath: "nhìn này, tôi không quan tâm đến không gian tên, chỉ cần tìm TẤT CẢ các nút có tên này, tôi thậm chí có thể cho bạn biết tên của không gian tên, chỉ không phải URI". Và đây là câu hỏi ở đây ...

Đây không phải là sự nhắc lại nhiều câu hỏi "biểu thức xpath của tôi không hoạt động vì tôi không biết về nhận thức không gian tên" như được tìm thấy ở đây hoặc ở đây . Tôi biết cách sử dụng nhận thức không gian tên. Chỉ không làm thế nào để thoát khỏi nó.


2
Nếu bạn không biết các lược đồ, làm thế nào bạn biết những yếu tố bạn muốn?
Paul Butcher


1
cảm ơn bạn đã chỉ ra, Alejandro. Tìm kiếm "bỏ qua không gian tên xpath" đáng lẽ đã tiết lộ điều này, nhưng nó đã không
kostja

2
@kostja: Đừng tìm kiếm với hộp tìm kiếm SO, nó vô dụng ... Hãy thử Google vào lần sau. Trên thực tế, điều này được khuyến khích bởi đội SO.

1
Tìm kiếm trang web của Google thực sự làm tốt hơn trong việc tìm kiếm những thứ hữu ích trên SO. Tôi tự hỏi tại sao nó không phải là một tùy chọn cho mỗi mặc định. Cảm ơn một lần nữa, Alejandro
Kostja

Câu trả lời:


164

Bạn có thể sử dụng local-name()hàm XPath. Thay vì chọn một nút như

/path/to/x:somenode

bạn có thể chọn tất cả các nút và lọc nút có tên cục bộ chính xác:

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

9
Bạn cũng có thể sử dụng local-name()để đề cập đến các thuộc tính là tốt, một cách không gian tên-không biết, xem: stackoverflow.com/q/21239181/274677
Marcus Junius Brutus


1
Quá đơn giản. đã cứu buổi chiều của tôi.
C Johnson


2

Bạn có thể sử dụng Namespace = false trên XmlTextReader

[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");
}

với :

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;

Để chọn một nút thông qua XPath, điều này hoạt động; Rất tiếc, bạn không thể lưu tài liệu do 'The 'xmlns' attribute is bound to the reserved namespacelỗi.
AutomatedChaos

2

Hoặc bạn có thể sử dụng name ():

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

Hoặc chỉ các thuộc tính tìm kiếm:

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

Nếu bạn mở xml dưới dạng một đối tượng powershell, nó sẽ bỏ qua các không gian tên:

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

0

Đó là ví dụ của tôi trong Qt C ++. Qt hỗ trợ XPath 2.0:

    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();

Đầu ra chương trình: "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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.