0

假设我有以下 XML:

<?xml version="1.0" encoding="UTF-8" ?>

<exchange xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://download.autodesk.com/us/navisworks/schemas/nw-exchange-12.0.xsd" units="ft" filename="" filepath="">
  <batchtest name="3636" internal_name="3636" units="ft">
    <clashtests>
      <clashtest name="Ducts VS Ducts" test_type="hard" status="new" tolerance="0.0000000000" merge_composites="0">
        <linkage mode="none"/>
        <left>
          <clashselection selfintersect="0" primtypes="1">
            <locator>/</locator>
          </clashselection>
        </left>
        <right>
          <clashselection selfintersect="0" primtypes="1">
            <locator>/</locator>
          </clashselection>
        </right>
        <rules/>
      </clashtest>
      <clashtest name="Ducts VS Cable Trays" test_type="hard" status="new" tolerance="0.0000000000" merge_composites="0">
        <linkage mode="none"/>
        <left>
          <clashselection selfintersect="0" primtypes="1">
            <locator>/</locator>
          </clashselection>
        </left>
        <right>
          <clashselection selfintersect="0" primtypes="1">
            <locator>/</locator>
          </clashselection>
        </right>
        <rules/>
      </clashtest>
      
      </batchtest>
</exchange>

我想在 Visual Studio 中使用 C# 来做这个图像

在此处输入图像描述

如图所示,我想将定位器节点的值更改为取决于碰撞测试节点的值。

4

3 回答 3

0

使用 xml linq :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            foreach (XElement clashtest in doc.Descendants("clashtest"))
            {
                string name = (string)clashtest.Attribute("name");
                string pattern = "(?'name1'.*)VS(?'name2'.*)";
                Match match = Regex.Match(name, pattern);
                string name1 = match.Groups["name1"].Value.Trim();
                string name2 = match.Groups["name2"].Value.Trim();

                List<XElement> locators = clashtest.Descendants("locator").ToList();
                locators[0].SetValue(name1);
                locators[1].SetValue(name2);
            }
        }
    }
}
于 2020-07-25T12:44:58.063 回答
0
var xml = XElement.Load("test.xml");
var clashtests = xml.Element("batchtest").Element("clashtests").Elements("clashtest");

foreach (var clashtest in clashtests)
{
    string name = clashtest.Attribute("name").Value;
    var values = name.Split(new[] { " VS " }, StringSplitOptions.None);

    var left = clashtest.Element("left").Element("clashselection").Element("locator");
    left.Value = values[0];

    var right = clashtest.Element("right").Element("clashselection").Element("locator");
    right.Value = values[1];
}
Console.WriteLine(xml);

指定完整路径:Element(...).Element(...)Descendants. 它对大型文档至关重要。

于 2020-07-25T13:05:39.303 回答
0

XSLT 有所谓的身份转换模式。

有用的链接:XSL 身份转换

下面的 XSLT 将按原样复制整个输入 XML,但定位器元素除外。找到定位器元素的那一刻,它将被新的所需值替换。

XSLT 函数substring-before()并轻松检索name属性值substring-after()的所需部分。

您所要做的就是从您的 c# 代码中调用 XSLT 转换。

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml" encoding="utf-8"/>

    <!-- IdentityTransform -->
    <xsl:template match="/ | @* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="locator[parent::clashselection/parent::left]">
        <locator>
            <xsl:value-of select="substring-before(ancestor::clashtest/@name, ' VS')"/>
        </locator>
    </xsl:template>

    <xsl:template match="locator[parent::clashselection/parent::right]">
        <locator>
            <xsl:value-of select="substring-after(ancestor::clashtest/@name, 'VS ')"/>
        </locator>
    </xsl:template>
</xsl:stylesheet>
于 2020-07-26T03:27:11.440 回答