3

我正在尝试根据找到的值读取/更新/删除 XML 文件。

我有一个名为123456.xml 的 XML,格式如下。

<ps>
  <p n="359" u="/ae/arabic/plan_book/plan_and_book.aspx"/>
  <p n="277" u="/ae/english/plan_book/plan_and_book.aspx"/>
  <p n="410" u="/ao/english/plan_book/plan_and_book.aspx"/>
</ps>

现在我在 java 中的新方法将获得 Filepath ( c://java/Files/12345.xml)、n(277 - 将在文件中检查的值) 和 U ("/de/english/plan_book/plan_and_book.aspx")。

我的java方法的逻辑如下,但真的不知道怎么写。

添加/附加方法逻辑:

  1. 打开文件c://java/Files/12345.xml
  2. 搜索所有节点并找到 n(277) 的值的基础。277 将只有一项记录
  3. 如果该值存在于文件中,则不需要更新,否则在 xml 文件中添加新节点,例如,如果 n 的值是 (777),因为该属性记录在文件中不存在,那么它将添加文件 ( <p n="777" u="/ao/english/plan_book/plan_and_book.aspx"/>) 中的新记录。
  4. 将更新的 XML 保存在同一位置。

删除方法逻辑:

  1. 打开文件c://java/Files/12345.xml
  2. 搜索所有节点,根据n(277)的值找到。277 将只有一项记录。
  3. 如果该值存在于节点属性“n”中,那么它将从 xml 中删除该节点,否则不需要更新。
  4. 将更新的 XML 保存在同一位置。

如果您分享上述实施的一些好的示例或链接,将不胜感激。

谢谢。

4

2 回答 2

3

在 XSLT 中指定这种处理通常比在命令式语言中更容易和简单(不需要 regEx)

下面的 XSLT 转换可以直接使用,或者它可以给出如何用另一种语言实现相同算法的想法:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pAction" select="'delete'"/>
 <xsl:param name="pN" select="277"/>
 <xsl:param name="pU" select="'/de/english/plan_book/plan_and_book.aspx'"/>

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

 <xsl:template match="ps">
  <ps>
    <xsl:apply-templates select=
     "*[not($pAction = 'delete')]
     |
      *[$pAction = 'delete' and not(@n = $pN)]
     "/>
    <xsl:if test="$pAction = 'add' and not(p[@n = $pN])">
      <p n="{$pN}" u="{$pU}"/>
    </xsl:if>
  </ps>
 </xsl:template>

 <xsl:template match="p">
  <xsl:choose>
    <xsl:when test="not(@n = $pN)">
      <xsl:call-template name="identity"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:if test="not($pAction = 'delete')">
          <xsl:call-template name="identity"/>
      </xsl:if>
     </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<ps>
    <p n="359" u="/ae/arabic/plan_book/plan_and_book.aspx"/>
    <p n="277" u="/ae/english/plan_book/plan_and_book.aspx"/>
    <p n="410" u="/ao/english/plan_book/plan_and_book.aspx"/>
</ps>

产生了想要的正确结果:

<ps>
   <p n="359" u="/ae/arabic/plan_book/plan_and_book.aspx"/>
   <p n="410" u="/ao/english/plan_book/plan_and_book.aspx"/>
</ps>

当参数$pAction 更改为

 <xsl:param name="pAction" select="''add'"/>

那么转换的结果是相同的 XML 文档(不变)。

当参数为

 <xsl:param name="pAction" select="''add'"/>

XML文档是

<ps>
    <p n="359" u="/ae/arabic/plan_book/plan_and_book.aspx"/>
    <p n="410" u="/ao/english/plan_book/plan_and_book.aspx"/>
</ps>

那么结果是

<ps>
   <p n="359" u="/ae/arabic/plan_book/plan_and_book.aspx"/>
   <p n="410" u="/ao/english/plan_book/plan_and_book.aspx"/>
   <p n="277" u="/de/english/plan_book/plan_and_book.aspx"/>
</ps>
于 2012-05-28T14:37:24.200 回答
1

当且仅当您的 XML 与您提供的示例一样简单时,您可以使用它:

以下代码将遍历所有匹配的<p>元素:

try {
    Pattern regex = Pattern.compile("(?is)(<p n=\"(\\d+)\" u=\"([^\"<>]+?)\"/>)");
    Matcher regexMatcher = regex.matcher(subjectString);
    while (regexMatcher.find()) {
        // matched text: regexMatcher.group()
        // match start: regexMatcher.start()
        // match end: regexMatcher.end()
    } 
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

要查找具有给定数字的特定节点(最好是字符串),请使用以下语法:

(?is)(<p n="#num_to_find#" )(u="[^"<>]+?"/>)

在哪里更改#num_to_find#您选择的数字。然后可以替换为:

$1#string_to_replacewith##

正则表达式解释

"(?is)" +                       // Match the remainder of the regex with the options: case insensitive (i); dot matches newline (s)
"(" +                           // Match the regular expression below and capture its match into backreference number 1
   "<p\\ n=\"#num_to_find#\"\\ " +     // Match the characters “&lt;p n="#num_to_find#" ” literally
")" +
"(" +                           // Match the regular expression below and capture its match into backreference number 2
   "u=\"" +                         // Match the characters “u="” literally
   "[^\"<>]" +                      // Match a single character NOT present in the list “"<>”
      "+?" +                          // Between one and unlimited times, as few times as possible, expanding as needed (lazy)
   "\"/>" +                         // Match the characters “"/>” literally
")"  

希望这可以帮助。

于 2012-05-28T14:18:20.743 回答