[xml] XPath로 네임 스페이스를 무시하는 방법

내 목표는 XPath를 사용하여 여러 네임 스페이스가있는 여러 xml 파일에서 특정 노드를 추출하는 것입니다. 네임 스페이스 URI를 아는 한 모든 것이 잘 작동합니다. 네임 스페이스 이름 자체는 일정하게 유지되지만 스키마 (XSD)는 때때로 클라이언트에서 생성됩니다. 그런 다음 기본적으로 세 가지 선택이 남았습니다.

  1. 아무 일도 일어나지 않기를 바라면서 네임 스페이스에 대해 하나의 스키마 만 사용하십시오 (확실 할 수 있습니까?).

  2. 문서의 자식 노드를 가져 와서 네임 스페이스 URI가있는 첫 번째 노드를 찾고 거기를 기대하고 올바른 것을 기대하면서 URI를 사용합니다. 여러 가지 이유로 잘못 될 수 있습니다.

  3. 어떻게 든 말해 xpath : “봐, 나는 네임 스페이스에 대해 신경 쓰지 않는다.이 이름을 가진 모든 노드를 찾아라. URI가 아니라 네임 스페이스의 이름도 말할 수있다”. 그리고 이것이 여기에있는 질문입니다 …

이것은 여기 또는 여기 에서 찾을 수있는 수많은 “내가 네임 스페이스 인식을 알지 못하기 때문에 내 xpath 표현식이 작동하지 않음”질문의 반복이 아닙니다 . 네임 스페이스 인식을 사용하는 방법을 알고 있습니다. 그것을 제거하는 방법이 아닙니다.



답변

local-name()XPath 기능을 사용할 수 있습니다 . 같은 노드를 선택하는 대신

/path/to/x:somenode

모든 노드를 선택하고 올바른 로컬 이름을 가진 것으로 필터링 할 수 있습니다.

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


답변

덜 자세한 구문으로 XPath2.0 에서 동일한 작업을 수행 할 수 있습니다 .

/path/to/*:somenode


답변

XmlTextReader에서 Namespace = false를 사용할 수 있습니다.

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

와 함께 :

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;


답변

또는 name ()을 사용할 수 있습니다.

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

또는 검색 속성 만 :

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

xml을 powershell 개체로 열면 네임 스페이스가 무시됩니다.

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


답변

Qt C ++의 예입니다. Qt는 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();

프로그램 출력 : "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>


답변