Javascript 获取 XML 中特定路径处的节点

发布于 2025-01-13 19:29:09 字数 1434 浏览 0 评论 0原文

我使用以下代码将一些 XML 读入 XmlDocument:

if (window.DOMParser)
{
    oParser = new DOMParser();
    oXml = oParser.parseFromString(this._code, "text/xml");
}
else // Internet Explorer
{
    oXml = new ActiveXObject("Microsoft.XMLDOM");
    oXml.async = false;
    oXml.loadXML(this._code);
}

测试 XML 如下所示:

<Macro>
  <StepCount>1</StepCount>
  <Step0>
    <StepType>CLOSEFORM</StepType>
    <Description>Close Form</Description>
    <OnSuccess>NEXTSTEP</OnSuccess>
    <OnFailure>SHOWERRORSANDSTOP</OnFailure>
    <CheckWithUser>False</CheckWithUser>
    <UserOptions>
        <Description>
            Are you sure you want to close the form?
        </Description>
    </UserOptions>
  </Step0>
</Macro>

XML 的设计使得其中的每个节点都有唯一的路径(因此标记 Step0 而不是只是步骤)。我知道 XML 通常不符合此限制。我正在尝试使用oXml.getElementsByTagName,它应该返回与标记名称匹配的节点数组。

我希望能够获取特定路径处的值,例如:/Macro/Step0/Description"

但是,如果我使用getElementsByTagName,我只能指定“Description”作为标签名称,这将返回两个节点,一个是我想要的,一个来自 XML 中更深层的节点。如果有多个步骤(Step1、Step2 等),我还会得到多个说明。我不感兴趣 是否有

另一种方法可以指定节点的路径?我不介意返回一个数组,因为在这种情况下,鉴于我所知道的限制,该数组将只包含一个元素。 document.evaluate,但这仅适用于 HTML 文档。

或者,如果我有使用 getElementsByTagName 获取的元素,如何获取它的完整路径?

I'm reading some XML into a XmlDocument using the following code:

if (window.DOMParser)
{
    oParser = new DOMParser();
    oXml = oParser.parseFromString(this._code, "text/xml");
}
else // Internet Explorer
{
    oXml = new ActiveXObject("Microsoft.XMLDOM");
    oXml.async = false;
    oXml.loadXML(this._code);
}

The test XML looks like this:

<Macro>
  <StepCount>1</StepCount>
  <Step0>
    <StepType>CLOSEFORM</StepType>
    <Description>Close Form</Description>
    <OnSuccess>NEXTSTEP</OnSuccess>
    <OnFailure>SHOWERRORSANDSTOP</OnFailure>
    <CheckWithUser>False</CheckWithUser>
    <UserOptions>
        <Description>
            Are you sure you want to close the form?
        </Description>
    </UserOptions>
  </Step0>
</Macro>

The XML has been designed so that each node within it has a unique path (hence the tag Step0 rather than just Step). I'm aware that XML doesn't conform to this restriction normally. I'm trying to use oXml.getElementsByTagName, which should return an array of nodes that match the tag name.

I'd like to be able to obtain the value of at a specific path, for example: /Macro/Step0/Description".

However, if I use getElementsByTagName, I can only specify "Description" as the tag name, which will return me two nodes, one I want and one from deeper in the XML. If there are multiple Steps (Step1, Step2 etc), I will also get multiple Descriptions back that I'm uninterested in.

Is there another method where I can specify the path to the node? I don't mind getting an array back, as in this case, the array will only ever contain one element, given the restriction indicated. I'm aware of document.evaluate, but that only applies to the HTML document.

Alternatively, if I have an element that I've obtained using getElementsByTagName how do I get it's full path?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

窝囊感情。 2025-01-20 19:29:09

好吧,我已经得出了一个解决方案,但可能还有更好的方法(我希望如此)。我使用的方法是使用 getElementsByTagName 获取与路径最后一个标记匹配的所有节点。遍历那些派生完整路径,并返回与完整路径匹配的第一个项目。不优雅,我当然不会在大型数据集上使用它,但它适用于我正在查看的数据量。

代码是:

function XmlDeriveFullPath(element) // returns the full path to the element within the XML, assuming that each node has a unique path
{
    var cPath = "/" + element.tagName;

    while ((element.parentNode != null) && (element.parentNode != undefined))
    {
        element = element.parentNode;
        if (element.tagName != null)
            cPath = "/" + element.tagName + cPath;
    }
    return cPath;
}

function XmlGetValueStr(oXml, cPath, cDefault = "") // Returns the value of the first node matching path. On error or no node, returns cDefault
{
    var aPath;
    var cLastTag;
    var i;
    var cFullPath;

    try
    {
        // get the last tag in the path
        aPath = cPath.split("/");
        cLastTag = aPath[aPath.length - 1];

        var elements = oXml.getElementsByTagName(cLastTag); // gives us a list of items with the same tag
        for (i=0; i<elements.length; i++)
        {
            cFullPath = XmlDeriveFullPath(elements[i]);
            if (cFullPath == cPath)
            {
                return elements[i].firstChild.nodeValue;
            }
        }

        return cDefault;
    }
    catch (e)
    {
        console.log("#XmlGetNodeStr: " + e);
        throw e;
    }
}

function XmlGetValueInt(oXml, cPath, iDefault = 0) // Returns the value of the first node matching path
{   
    var cValue;
    var iValue;

    try
    {
        cValue = XmlGetNodeStr(oXml, cPath, "");
        iValue = parseInt(cValue);
        return iValue;
    }
    catch (e)
    {
        console.log("#XmlGetNodeInt: " + e);
        return iDefault;
    }
}

iStepCount = XmlGetValueInt(oXml, "/Macro/StepCount", 0);

如果有人确实有更好的解决方案,请发布。

Well, I've derived an solution, but there may be a better way (I hope so). The approach I've used is to get all nodes that match the last tag of the path using getElementsByTagName. The run through those deriving the full path, and returning the first item that matches the full path. Not elegant, and I certainly wouldn't use it on a large dataset, but it works for the volume of data I'm looking at.

The code is:

function XmlDeriveFullPath(element) // returns the full path to the element within the XML, assuming that each node has a unique path
{
    var cPath = "/" + element.tagName;

    while ((element.parentNode != null) && (element.parentNode != undefined))
    {
        element = element.parentNode;
        if (element.tagName != null)
            cPath = "/" + element.tagName + cPath;
    }
    return cPath;
}

function XmlGetValueStr(oXml, cPath, cDefault = "") // Returns the value of the first node matching path. On error or no node, returns cDefault
{
    var aPath;
    var cLastTag;
    var i;
    var cFullPath;

    try
    {
        // get the last tag in the path
        aPath = cPath.split("/");
        cLastTag = aPath[aPath.length - 1];

        var elements = oXml.getElementsByTagName(cLastTag); // gives us a list of items with the same tag
        for (i=0; i<elements.length; i++)
        {
            cFullPath = XmlDeriveFullPath(elements[i]);
            if (cFullPath == cPath)
            {
                return elements[i].firstChild.nodeValue;
            }
        }

        return cDefault;
    }
    catch (e)
    {
        console.log("#XmlGetNodeStr: " + e);
        throw e;
    }
}

function XmlGetValueInt(oXml, cPath, iDefault = 0) // Returns the value of the first node matching path
{   
    var cValue;
    var iValue;

    try
    {
        cValue = XmlGetNodeStr(oXml, cPath, "");
        iValue = parseInt(cValue);
        return iValue;
    }
    catch (e)
    {
        console.log("#XmlGetNodeInt: " + e);
        return iDefault;
    }
}

iStepCount = XmlGetValueInt(oXml, "/Macro/StepCount", 0);

If someone does have a better solution, please post.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文